diff --git a/package.json b/package.json index 55bd9be2dc797590c2f318c154bf257ef6adbb1c..43828fc9d97df3239a326bab4eab5c15d35a5e49 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ ], "scripts": { "test": "lerna run test", + "format": "lerna run format", "build": "lerna run build", "i18next": "lerna run i18next", "version-patch": "lerna version patch", diff --git a/packages/app-shell/.eslintrc.json b/packages/app-shell/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/app-shell/.eslintrc.json +++ b/packages/app-shell/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/app-shell/.prettierignore b/packages/app-shell/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..9f6b5e8e183caf09d6144a683354474d673c1337 --- /dev/null +++ b/packages/app-shell/.prettierignore @@ -0,0 +1,2 @@ +node_modules/ +/dist \ No newline at end of file diff --git a/packages/app-shell/.prettierrc.json b/packages/app-shell/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/app-shell/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/app-shell/assets/example.metadata.json b/packages/app-shell/assets/example.metadata.json index ab2e09786b9d03995bf48c112c961ed4634fd79f..69973d9656ec0ccd52926993d4285013fac6c308 100644 --- a/packages/app-shell/assets/example.metadata.json +++ b/packages/app-shell/assets/example.metadata.json @@ -1,17 +1,17 @@ { - "element": "dbp-activity-example", - "module_src": "dbp-activity-example.js", - "routing_name": "activity-example", - "name": { - "de": "Beispielaktivität", - "en": "Example Activity" - }, - "short_name": { - "de": "Beispielaktivität", - "en": "Example Activity" - }, - "description": { - "de": "Eine Beschreibung", - "en": "A Description" - } + "element": "dbp-activity-example", + "module_src": "dbp-activity-example.js", + "routing_name": "activity-example", + "name": { + "de": "Beispielaktivität", + "en": "Example Activity" + }, + "short_name": { + "de": "Beispielaktivität", + "en": "Example Activity" + }, + "description": { + "de": "Eine Beschreibung", + "en": "A Description" + } } diff --git a/packages/app-shell/assets/example.topic.metadata.json b/packages/app-shell/assets/example.topic.metadata.json index 108e6eba66a0aea606ecc3447f471bf106a90766..6f868cb56cc92580a95105a1fc731eb4fd8f4a9a 100644 --- a/packages/app-shell/assets/example.topic.metadata.json +++ b/packages/app-shell/assets/example.topic.metadata.json @@ -1,20 +1,17 @@ { - "name": { - "de": "Beispiel", - "en": "Example" - }, - "short_name": { - "de": "Beispiel", - "en": "Example" - }, - "description": { - "de": "Ich bin eine Beschreibung der Applikation", - "en": "I am a description of this application" - }, - "routing_name": "example", - "activities": [ - {"path": "example.metadata.json"}, - {"path": "example2.metadata.json"} - ], - "attributes": [] -} \ No newline at end of file + "name": { + "de": "Beispiel", + "en": "Example" + }, + "short_name": { + "de": "Beispiel", + "en": "Example" + }, + "description": { + "de": "Ich bin eine Beschreibung der Applikation", + "en": "I am a description of this application" + }, + "routing_name": "example", + "activities": [{"path": "example.metadata.json"}, {"path": "example2.metadata.json"}], + "attributes": [] +} diff --git a/packages/app-shell/assets/example2.metadata.json b/packages/app-shell/assets/example2.metadata.json index e91d28073c6dcb22940d165a7503b5c4684f54f1..dbf7a427739c4184ebf420f4b30e0b44115e938a 100644 --- a/packages/app-shell/assets/example2.metadata.json +++ b/packages/app-shell/assets/example2.metadata.json @@ -1,17 +1,17 @@ { - "element": "dbp-activity-example", - "module_src": "dbp-activity-example.js", - "routing_name": "activity-example2", - "name": { - "de": "Beispielaktivität 2", - "en": "Example Activity 2" - }, - "short_name": { - "de": "Beispielaktivität 2", - "en": "Example Activity 2" - }, - "description": { - "de": "Eine Beschreibung", - "en": "A Description" - } + "element": "dbp-activity-example", + "module_src": "dbp-activity-example.js", + "routing_name": "activity-example2", + "name": { + "de": "Beispielaktivität 2", + "en": "Example Activity 2" + }, + "short_name": { + "de": "Beispielaktivität 2", + "en": "Example Activity 2" + }, + "description": { + "de": "Eine Beschreibung", + "en": "A Description" + } } diff --git a/packages/app-shell/i18next-scanner.config.js b/packages/app-shell/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/app-shell/i18next-scanner.config.js +++ b/packages/app-shell/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json index 882442d86e96f54b57cbb7a1da2fb347cd435652..3949060dc1fef602008c4fae0d366564a3102ede 100644 --- a/packages/app-shell/package.json +++ b/packages/app-shell/package.json @@ -1,58 +1,62 @@ { - "name": "@dbp-toolkit/app-shell", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/app-shell", - "version": "0.2.7", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/app-shell" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "glob": "^7.1.6", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-emit-ejs": "^3.1.0", - "rollup-plugin-serve": "^1.0.1" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@dbp-toolkit/language-select": "^0.2.2", - "@dbp-toolkit/matomo": "^0.2.2", - "@dbp-toolkit/notification": "^0.2.2", - "@dbp-toolkit/person-profile": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "i18next": "^21.4.2", - "lit": "^2.0.0", - "universal-router": "^9.0.1" - }, - "scripts": { - "i18next": "i18next-scanner", - "build": "npm run build-local", - "build-local": "rollup -c", - "build-test": "rollup -c --environment BUILD:test", - "watch": "npm run watch-local", - "watch-local": "rollup -c --watch", - "test": "npm run build-test && karma start --singleRun", - "lint": "eslint ." - } + "name": "@dbp-toolkit/app-shell", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/app-shell", + "version": "0.2.7", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/app-shell" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "glob": "^7.1.6", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-emit-ejs": "^3.1.0", + "rollup-plugin-serve": "^1.0.1" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@dbp-toolkit/language-select": "^0.2.2", + "@dbp-toolkit/matomo": "^0.2.2", + "@dbp-toolkit/notification": "^0.2.2", + "@dbp-toolkit/person-profile": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "i18next": "^21.4.2", + "lit": "^2.0.0", + "universal-router": "^9.0.1" + }, + "scripts": { + "i18next": "i18next-scanner", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "build": "npm run build-local", + "build-local": "rollup -c", + "build-test": "rollup -c --environment BUILD:test", + "watch": "npm run watch-local", + "watch-local": "rollup -c --watch", + "test": "npm run build-test && karma start --singleRun", + "lint": "eslint ." + } } diff --git a/packages/app-shell/rollup.config.js b/packages/app-shell/rollup.config.js index d51e613ee37763f6d21931ee179f6e1bd72b286d..9eedee2b54da1b515d1860cd8471fd8fc56a430a 100644 --- a/packages/app-shell/rollup.config.js +++ b/packages/app-shell/rollup.config.js @@ -7,38 +7,48 @@ import del from 'rollup-plugin-delete'; import json from '@rollup/plugin-json'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build !='test') ? ['src/dbp-app-shell.js', 'src/dbp-activity-example.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-app-shell.js', 'src/dbp-activity-example.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true - }, + sourcemap: true, + }, plugins: [ del({ - targets: 'dist/*' - }), + targets: 'dist/*', + }), resolve(), commonjs(), json(), copy({ targets: [ - {src: 'assets/silent-check-sso.html', dest:'dist'}, + {src: 'assets/silent-check-sso.html', dest: 'dist'}, {src: 'assets/index.html', dest: 'dist'}, {src: 'assets/*.json', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({ - contentBase: 'dist', - historyApiFallback: '/index.html', - host: '127.0.0.1', port: 8002}) : false - ] - } -})(); \ No newline at end of file + process.env.ROLLUP_WATCH === 'true' + ? serve({ + contentBase: 'dist', + historyApiFallback: '/index.html', + host: '127.0.0.1', + port: 8002, + }) + : false, + ], + }; +})(); diff --git a/packages/app-shell/src/app-shell.js b/packages/app-shell/src/app-shell.js index 9b0ed32674efb1d73719c808c435e808494d7fbe..fb573076a6088adace45958d2cc889cd80651ee0 100644 --- a/packages/app-shell/src/app-shell.js +++ b/packages/app-shell/src/app-shell.js @@ -13,8 +13,8 @@ import {Router} from './router.js'; import {BuildInfo} from './build-info.js'; import {send as notify} from '@dbp-toolkit/common/notification'; import {appWelcomeMeta} from './dbp-app-shell-welcome.js'; -import {MatomoElement} from "@dbp-toolkit/matomo/src/matomo"; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; +import {MatomoElement} from '@dbp-toolkit/matomo/src/matomo'; +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; /** * In case the application gets updated future dynamic imports might fail. @@ -31,9 +31,9 @@ const importNotify = async (i18n, promise) => { } catch (error) { console.log(error); notify({ - "body": i18n.t('page-updated-needs-reload'), - "type": "info", - "icon": "warning" + body: i18n.t('page-updated-needs-reload'), + type: 'info', + icon: 'warning', }); throw error; } @@ -73,24 +73,23 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { this.initateOpenMenu = false; this.auth = {}; - } static get scopedElements() { return { - 'dbp-language-select': LanguageSelect, - 'dbp-build-info': BuildInfo, - 'dbp-auth-keycloak': AuthKeycloak, - 'dbp-auth-menu-button': AuthMenuButton, - 'dbp-theme-switcher': ThemeSwitcher, - 'dbp-notification': Notification, - 'dbp-icon': Icon, - 'dbp-matomo': MatomoElement, + 'dbp-language-select': LanguageSelect, + 'dbp-build-info': BuildInfo, + 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-auth-menu-button': AuthMenuButton, + 'dbp-theme-switcher': ThemeSwitcher, + 'dbp-notification': Notification, + 'dbp-icon': Icon, + 'dbp-matomo': MatomoElement, }; } onAttributeObserved(mutationsList, observer) { - for(let mutation of mutationsList) { + for (let mutation of mutationsList) { if (mutation.type === 'attributes') { const key = mutation.attributeName; const value = mutation.target.getAttribute(key); @@ -109,22 +108,23 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { let metadata = {}; let routes = []; - const result = await (await fetch(topicURL, { - headers: {'Content-Type': 'application/json'} - })).json(); + const result = await ( + await fetch(topicURL, { + headers: {'Content-Type': 'application/json'}, + }) + ).json(); this.topic = result; const fetchOne = async (url) => { - const result = await fetch(url, { - headers: {'Content-Type': 'application/json'} + const result = await fetch(url, { + headers: {'Content-Type': 'application/json'}, }); - if (!result.ok) - throw result; + if (!result.ok) throw result; const jsondata = await result.json(); - if (jsondata["element"] === undefined) - throw new Error("no element defined in metadata"); + if (jsondata['element'] === undefined) + throw new Error('no element defined in metadata'); return jsondata; }; @@ -132,7 +132,11 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { let promises = []; for (const activity of result.activities) { const actURL = new URL(activity.path, new URL(topicURL, window.location).href).href; - promises.push([activity.visible === undefined || activity.visible, actURL, fetchOne(actURL)]); + promises.push([ + activity.visible === undefined || activity.visible, + actURL, + fetchOne(actURL), + ]); } for (const [visible, actURL, p] of promises) { @@ -151,11 +155,11 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { if (!this.noWelcomePage) { // Inject the welcome activity - routes.unshift("welcome"); + routes.unshift('welcome'); metadata = Object.assign(metadata, { - "welcome": appWelcomeMeta, + welcome: appWelcomeMeta, }); - customElements.get("dbp-app-shell-welcome").app = this; + customElements.get('dbp-app-shell-welcome').app = this; } // this also triggers a rebuilding of the menu @@ -163,11 +167,8 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { this.routes = routes; // Switch to the first route if none is selected - if (!this.activeView) - this.switchComponent(routes[0]); - else - this.switchComponent(this.activeView); - + if (!this.activeView) this.switchComponent(routes[0]); + else this.switchComponent(this.activeView); } initRouter() { @@ -179,7 +180,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { lang: this.lang, component: '', }; - } + }, }, { path: '/:lang', @@ -191,14 +192,14 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { lang: params.lang, component: '', }; - } + }, }, { name: 'mainRoute', path: '/:component', action: (context, params) => { // remove the additional parameters added by Keycloak - let componentTag = params.component.toLowerCase().replace(/&.+/,""); + let componentTag = params.component.toLowerCase().replace(/&.+/, ''); return { lang: params.lang, component: componentTag, @@ -209,28 +210,32 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { }, ]; - this.router = new Router(routes, { - routeName: 'mainRoute', - getState: () => { - let state = { - component: this.activeView, - lang: this.lang, - }; - return state; - }, - setState: (state) => { - this.updateLangIfChanged(state.lang); - this.switchComponent(state.component); + this.router = new Router( + routes, + { + routeName: 'mainRoute', + getState: () => { + let state = { + component: this.activeView, + lang: this.lang, + }; + return state; + }, + setState: (state) => { + this.updateLangIfChanged(state.lang); + this.switchComponent(state.component); + }, + getDefaultState: () => { + return { + lang: 'de', + component: this.routes[0], + }; + }, }, - getDefaultState: () => { - return { - lang: 'de', - component: this.routes[0], - }; - } - }, { - baseUrl: new URL(this.basePath, window.location).pathname.replace(/\/$/, ''), - }); + { + baseUrl: new URL(this.basePath, window.location).pathname.replace(/\/$/, ''), + } + ); this.router.setStateFromCurrentLocation(); } @@ -238,35 +243,34 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { static get properties() { return { ...super.properties, - lang: { type: String, reflect: true }, - src: { type: String }, - basePath: { type: String, attribute: 'base-path' }, - activeView: { type: String, attribute: false}, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - keycloakConfig: { type: Object, attribute: 'keycloak-config' }, - metadata: { type: Object, attribute: false }, - visibleRoutes: { type: Array, attribute: false }, - topic: { type: Object, attribute: false }, - subtitle: { type: String, attribute: false }, - description: { type: String, attribute: false }, - _loginStatus: { type: Boolean, attribute: false }, - _roles: { type: Array, attribute: false }, - matomoUrl: { type: String, attribute: "matomo-url" }, - matomoSiteId: { type: Number, attribute: "matomo-site-id" }, - noWelcomePage: { type: Boolean, attribute: "no-welcome-page" }, - gitInfo: { type: String, attribute: "git-info" }, - buildUrl: { type: String, attribute: "build-url" }, - buildTime: { type: String, attribute: "build-time" }, - env: { type: String }, - auth: { type: Object }, + lang: {type: String, reflect: true}, + src: {type: String}, + basePath: {type: String, attribute: 'base-path'}, + activeView: {type: String, attribute: false}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + keycloakConfig: {type: Object, attribute: 'keycloak-config'}, + metadata: {type: Object, attribute: false}, + visibleRoutes: {type: Array, attribute: false}, + topic: {type: Object, attribute: false}, + subtitle: {type: String, attribute: false}, + description: {type: String, attribute: false}, + _loginStatus: {type: Boolean, attribute: false}, + _roles: {type: Array, attribute: false}, + matomoUrl: {type: String, attribute: 'matomo-url'}, + matomoSiteId: {type: Number, attribute: 'matomo-site-id'}, + noWelcomePage: {type: Boolean, attribute: 'no-welcome-page'}, + gitInfo: {type: String, attribute: 'git-info'}, + buildUrl: {type: String, attribute: 'build-url'}, + buildTime: {type: String, attribute: 'build-time'}, + env: {type: String}, + auth: {type: Object}, }; } connectedCallback() { super.connectedCallback(); - if (this.src) - this.fetchMetadata(this.src); + if (this.src) this.fetchMetadata(this.src); this.initRouter(); } @@ -295,48 +299,48 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { case 'lang': this._i18n.changeLanguage(this.lang); // For screen readers - document.documentElement.setAttribute("lang", this.lang); + document.documentElement.setAttribute('lang', this.lang); this.router.update(); - this.subtitle = this.activeMetaDataText("short_name"); - this.description = this.activeMetaDataText("description"); + this.subtitle = this.activeMetaDataText('short_name'); + this.description = this.activeMetaDataText('description'); // send a dbp-lang event with the language this.dispatchEvent( new CustomEvent('dbp-lang', { bubbles: true, composed: true, - detail: this.lang + detail: this.lang, }) ); - break; + break; case 'metadata': - { - this._updateVisibleRoutes(); - } - break; - case 'auth': - { - if (this.auth.person) { - this._roles = this.auth.person['roles']; - } else { - this._roles = []; + { + this._updateVisibleRoutes(); } - this._updateVisibleRoutes(); + break; + case 'auth': + { + if (this.auth.person) { + this._roles = this.auth.person['roles']; + } else { + this._roles = []; + } + this._updateVisibleRoutes(); - const loginStatus = this.auth['login-status']; - if (loginStatus !== this._loginStatus) { - console.log('Login status: ' + loginStatus); - } + const loginStatus = this.auth['login-status']; + if (loginStatus !== this._loginStatus) { + console.log('Login status: ' + loginStatus); + } - this._loginStatus = loginStatus; + this._loginStatus = loginStatus; - // Clear the session storage when the user logs out - if (this._loginStatus === 'logging-out') { - sessionStorage.clear(); + // Clear the session storage when the user logs out + if (this._loginStatus === 'logging-out') { + sessionStorage.clear(); + } } - } - break; + break; } }); @@ -347,9 +351,9 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { e.preventDefault(); // if not the current page was clicked we need to check if the page can be left - if (!e.currentTarget.className.includes("selected")) { + if (!e.currentTarget.className.includes('selected')) { // simulate a "beforeunload" event - const event = new CustomEvent("beforeunload", { + const event = new CustomEvent('beforeunload', { bubbles: true, cancelable: true, }); @@ -370,21 +374,20 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { onLanguageChanged(e) { const newLang = e.detail.lang; - const changed = (this.lang !== newLang); + const changed = this.lang !== newLang; this.lang = newLang; if (changed) { this.router.update(); - this.subtitle = this.activeMetaDataText("short_name"); - this.description = this.activeMetaDataText("description"); + this.subtitle = this.activeMetaDataText('short_name'); + this.description = this.activeMetaDataText('description'); } } switchComponent(componentTag) { let offset = window.pageYOffset; - const changed = (componentTag !== this.activeView); + const changed = componentTag !== this.activeView; this.activeView = componentTag; - if (changed) - this.router.update(); + if (changed) this.router.update(); const metadata = this.metadata[componentTag]; if (metadata === undefined) { @@ -392,21 +395,27 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { } let updateFunc = () => { - if (offset > 0) { - - const header = this.shadowRoot.querySelector("header"); - const title = this.shadowRoot.querySelector("#headline"); + const header = this.shadowRoot.querySelector('header'); + const title = this.shadowRoot.querySelector('#headline'); if (header === null || title === null) { return; } let style = getComputedStyle(title); - let marginTop = isNaN(parseInt(style.marginTop, 10)) ? 0 : parseInt(style.marginTop, 10); - let marginBottom = isNaN(parseInt(style.marginBottom, 10)) ? 0 : parseInt(style.marginBottom, 10); - - let topValue = header.getBoundingClientRect().height + title.getBoundingClientRect().height + marginTop + marginBottom; + let marginTop = isNaN(parseInt(style.marginTop, 10)) + ? 0 + : parseInt(style.marginTop, 10); + let marginBottom = isNaN(parseInt(style.marginBottom, 10)) + ? 0 + : parseInt(style.marginBottom, 10); + + let topValue = + header.getBoundingClientRect().height + + title.getBoundingClientRect().height + + marginTop + + marginBottom; if (offset < topValue) { window.scrollTo(0, offset); @@ -415,8 +424,8 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { } } this.updatePageTitle(); - this.subtitle = this.activeMetaDataText("short_name"); - this.description = this.activeMetaDataText("description"); + this.subtitle = this.activeMetaDataText('short_name'); + this.description = this.activeMetaDataText('description'); }; // If it is empty assume the element is already registered through other means @@ -425,21 +434,25 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { return; } - importNotify(this._i18n, import(metadata.module_src)).then(() => { - updateFunc(); - }).catch((e) => { - console.error(`Error loading ${ metadata.element }`); - throw e; - }); + importNotify(this._i18n, import(metadata.module_src)) + .then(() => { + updateFunc(); + }) + .catch((e) => { + console.error(`Error loading ${metadata.element}`); + throw e; + }); } metaDataText(routingName, key) { const metadata = this.metadata[routingName]; - return metadata !== undefined && metadata[key] !== undefined ? metadata[key][this.lang] : ''; + return metadata !== undefined && metadata[key] !== undefined + ? metadata[key][this.lang] + : ''; } topicMetaDataText(key) { - return (this.topic[key] !== undefined) ? this.topic[key][this.lang] : ''; + return this.topic[key] !== undefined ? this.topic[key][this.lang] : ''; } activeMetaDataText(key) { @@ -447,12 +460,14 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { } updatePageTitle() { - document.title = `${this.topicMetaDataText('name')} - ${this.activeMetaDataText("short_name")}`; + document.title = `${this.topicMetaDataText('name')} - ${this.activeMetaDataText( + 'short_name' + )}`; } toggleMenu() { - const menu = this.shadowRoot.querySelector("ul.menu"); - const subtitle = this.shadowRoot.querySelector("h2.subtitle"); + const menu = this.shadowRoot.querySelector('ul.menu'); + const subtitle = this.shadowRoot.querySelector('h2.subtitle'); if (menu === null || subtitle === null) { return; @@ -466,18 +481,22 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { let topValue = subtitle.getBoundingClientRect().bottom; let isMenuOverflow = this.menuHeight + topValue >= window.innerHeight ? true : false; - + if (isMenuOverflow && !menu.classList.contains('hidden')) { - menu.setAttribute('style', 'position: fixed;top: ' + topValue + 'px;bottom: 0;border-bottom: 0;overflow-y: auto;'); + menu.setAttribute( + 'style', + 'position: fixed;top: ' + + topValue + + 'px;bottom: 0;border-bottom: 0;overflow-y: auto;' + ); menu.scrollTop = 0; document.body.setAttribute('style', 'overflow:hidden;'); - } else if (isMenuOverflow && menu.classList.contains('hidden')) { document.body.removeAttribute('style', 'overflow:hidden;'); menu.removeAttribute('style'); } - const chevron = this.shadowRoot.querySelector("#menu-chevron-icon"); + const chevron = this.shadowRoot.querySelector('#menu-chevron-icon'); if (chevron !== null) { chevron.name = menu.classList.contains('hidden') ? 'chevron-down' : 'chevron-up'; } @@ -485,8 +504,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { if (!menu.classList.contains('hidden')) { document.addEventListener('click', this.boundCloseMenuHandler); this.initateOpenMenu = true; - } - else { + } else { document.removeEventListener('click', this.boundCloseMenuHandler); menu.removeAttribute('style'); } @@ -497,9 +515,8 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { this.initateOpenMenu = false; return; } - const menu = this.shadowRoot.querySelector("ul.menu"); - if (menu && !menu.classList.contains('hidden')) - this.toggleMenu(); + const menu = this.shadowRoot.querySelector('ul.menu'); + if (menu && !menu.classList.contains('hidden')) this.toggleMenu(); } static get styles() { @@ -509,7 +526,9 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { ${commonStyles.getGeneralCSS()} ${commonStyles.getLinkCss()} - .hidden {display: none} + .hidden { + display: none; + } h1.title { margin-bottom: 0; @@ -520,7 +539,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { display: grid; grid-template-columns: minmax(180px, 17%) minmax(0, auto); grid-template-rows: min-content min-content 1fr min-content; - grid-template-areas: "header header" "headline headline" "sidebar main" "footer footer"; + grid-template-areas: 'header header' 'headline headline' 'sidebar main' 'footer footer'; max-width: 1400px; margin: auto; min-height: 100vh; @@ -535,16 +554,30 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { display: grid; grid-template-columns: 50% 1px auto; grid-template-rows: 60px 60px; - grid-template-areas: "hd1-left hd1-middle hd1-right" "hd2-left . hd2-right"; + grid-template-areas: 'hd1-left hd1-middle hd1-right' 'hd2-left . hd2-right'; width: 100%; max-width: 1060px; margin: 0 auto; } - aside { grid-area: sidebar; margin: 15px 15px; } - #headline { grid-area: headline; margin: 20px 0 30px 0; text-align: center; } - main { grid-area: main; margin: 15px 15px; } - footer { grid-area: footer; margin: 15px; text-align: right; } + aside { + grid-area: sidebar; + margin: 15px 15px; + } + #headline { + grid-area: headline; + margin: 20px 0 30px 0; + text-align: center; + } + main { + grid-area: main; + margin: 15px 15px; + } + footer { + grid-area: footer; + margin: 15px; + text-align: right; + } header .hd1-left { display: flex; @@ -558,8 +591,8 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { -webkit-align-items: center; gap: 10px; } - - header .hd1-left #lang-select{ + + header .hd1-left #lang-select { padding-right: 10px; padding-left: 10px; } @@ -567,7 +600,12 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { header .hd1-middle { grid-area: hd1-middle; background-color: var(--dbp-text); - background: linear-gradient(180deg, var(--dbp-text) 0%, var(--dbp-text) 85%, rgba(0,0,0,0) 90%); + background: linear-gradient( + 180deg, + var(--dbp-text) 0%, + var(--dbp-text) 85%, + rgba(0, 0, 0, 0) 90% + ); } header .hd1-right { @@ -614,7 +652,8 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { display: inline; } - aside ul.menu, footer ul.menu { + aside ul.menu, + footer ul.menu { list-style: none; } @@ -628,7 +667,8 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { flex-wrap: wrap; } - footer > *, footer slot > * { + footer > *, + footer slot > * { margin: 0.5em 0 0 1em; } @@ -675,7 +715,6 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { font-weight: bolder; padding-left: 0.5em; padding-right: 0.3em; - } aside .subtitle { @@ -692,15 +731,17 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { display: block; } - a { transition: background-color 0.15s ease 0s, color 0.15s ease 0s; } + a { + transition: background-color 0.15s ease 0s, color 0.15s ease 0s; + } .description { text-align: left; margin-bottom: 1rem; display: none; } - - #dbp-notification{ + + #dbp-notification { z-index: 99999; } @@ -708,15 +749,16 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { #main { grid-template-columns: minmax(0, auto); grid-template-rows: min-content min-content min-content 1fr min-content; - grid-template-areas: "header" "headline" "sidebar" "main" "footer"; + grid-template-areas: 'header' 'headline' 'sidebar' 'main' 'footer'; } header { grid-template-rows: 40px; - grid-template-areas: "hd1-left hd1-middle hd1-right"; + grid-template-areas: 'hd1-left hd1-middle hd1-right'; } - header .hd2-left, header .hd2-right { + header .hd2-left, + header .hd2-right { display: none; } @@ -805,13 +847,16 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { } _onActivityAdded(element) { - for(const key of this.topic.attributes || []) { + for (const key of this.topic.attributes || []) { let value = sessionStorage.getItem('dbp-attr-' + key); if (value !== null) { element.setAttribute(key, value); } } - this._attrObserver.observe(element, {attributes: true, attributeFilter: this.topic.attributes}); + this._attrObserver.observe(element, { + attributes: true, + attributeFilter: this.topic.attributes, + }); element.addEventListener('dbp-show-activity', this._onShowActivityEvent); } @@ -821,29 +866,28 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { } track(action, message) { - this.sendSetPropertyEvent('analytics-event', {'category': action, 'action': message}, true); + this.sendSetPropertyEvent('analytics-event', {category: action, action: message}, true); } _renderActivity() { const act = this.metadata[this.activeView]; - if (act === undefined) - return html``; + if (act === undefined) return html``; - const elm = this._createActivityElement(act); + const elm = this._createActivityElement(act); // add subscriptions for the provider component if (act.subscribe !== undefined) { - elm.setAttribute("subscribe", act.subscribe); + elm.setAttribute('subscribe', act.subscribe); } // only add the entry-point-url attribute if it isn't subscribed - if (act.subscribe === undefined || !act.subscribe.includes("entry-point-url:")) { - elm.setAttribute("entry-point-url", this.entryPointUrl); + if (act.subscribe === undefined || !act.subscribe.includes('entry-point-url:')) { + elm.setAttribute('entry-point-url', this.entryPointUrl); } // only add the lang attribute if it isn't subscribed - if (act.subscribe === undefined || !act.subscribe.includes("lang:")) { - elm.setAttribute("lang", this.lang); + if (act.subscribe === undefined || !act.subscribe.includes('lang:')) { + elm.setAttribute('lang', this.lang); } return elm; } @@ -871,7 +915,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { this.visibleRoutes = visibleRoutes; - const event = new CustomEvent("visibility-changed", { + const event = new CustomEvent('visibility-changed', { bubbles: false, cancelable: true, }); @@ -881,13 +925,13 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { render() { let i18n = this._i18n; - const getSelectClasses = (name => { + const getSelectClasses = (name) => { return classMap({selected: this.activeView === name}); - }); + }; // We hide the app until we are either fully logged in or logged out // At the same time when we hide the main app we show the main slot (e.g. a loading spinner) - const appHidden = (this._loginStatus === 'unknown' || this._loginStatus === 'logging-in'); + const appHidden = this._loginStatus === 'unknown' || this._loginStatus === 'logging-in'; const mainClassMap = classMap({hidden: appHidden}); const slotClassMap = classMap({hidden: !appHidden}); @@ -896,50 +940,146 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { // XXX: Safari 11 doesn't like CSS being applied to slots or via HTML, // so we have to remove the slot instead of hiding it // select slots with no name attribute - const slot = this.shadowRoot.querySelector("slot:not([name])"); - if (slot) - slot.remove(); + const slot = this.shadowRoot.querySelector('slot:not([name])'); + if (slot) slot.remove(); }); } - const prodClassMap = classMap({hidden: this.env === 'production' || this.env === 'demo' || this.env === ''}); + const prodClassMap = classMap({ + hidden: this.env === 'production' || this.env === 'demo' || this.env === '', + }); this.updatePageTitle(); // build the menu let menuTemplates = []; for (let routingName of this.visibleRoutes) { - menuTemplates.push(html`<li><a @click="${(e) => this.onMenuItemClick(e)}" href="${this.router.getPathname({component: routingName})}" data-nav class="${getSelectClasses(routingName)}" title="${this.metaDataText(routingName, "description")}">${this.metaDataText(routingName, "short_name")}</a></li>`); + menuTemplates.push( + html` + <li> + <a + @click="${(e) => this.onMenuItemClick(e)}" + href="${this.router.getPathname({component: routingName})}" + data-nav + class="${getSelectClasses(routingName)}" + title="${this.metaDataText(routingName, 'description')}"> + ${this.metaDataText(routingName, 'short_name')} + </a> + </li> + ` + ); } const kc = this.keycloakConfig; return html` <slot class="${slotClassMap}"></slot> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" url="${kc.url}" realm="${kc.realm}" client-id="${kc.clientId}" silent-check-sso-redirect-uri="${kc.silentCheckSsoRedirectUri || ''}" scope="${kc.scope || ''}" idp-hint="${kc.idpHint || ''}" ?force-login="${kc.forceLogin}" ?try-login="${!kc.forceLogin}"></dbp-auth-keycloak> - <dbp-matomo subscribe="auth,analytics-event" endpoint="${this.matomoUrl}" site-id="${this.matomoSiteId}" git-info="${this.gitInfo}"></dbp-matomo> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + url="${kc.url}" + realm="${kc.realm}" + client-id="${kc.clientId}" + silent-check-sso-redirect-uri="${kc.silentCheckSsoRedirectUri || ''}" + scope="${kc.scope || ''}" + idp-hint="${kc.idpHint || ''}" + ?force-login="${kc.forceLogin}" + ?try-login="${!kc.forceLogin}"></dbp-auth-keycloak> + <dbp-matomo + subscribe="auth,analytics-event" + endpoint="${this.matomoUrl}" + site-id="${this.matomoSiteId}" + git-info="${this.gitInfo}"></dbp-matomo> <div class="${mainClassMap}" id="root"> <div id="main"> <dbp-notification id="dbp-notification" lang="${this.lang}"></dbp-notification> <header> <slot name="header"> <div class="hd1-left"> - <dbp-theme-switcher subscribe="themes,dark-mode-theme-override" lang="${this.lang}"></dbp-theme-switcher> - <dbp-language-select id="lang-select" lang="${this.lang}"></dbp-language-select> - </div> - <div class="hd1-middle"> + <dbp-theme-switcher + subscribe="themes,dark-mode-theme-override" + lang="${this.lang}"></dbp-theme-switcher> + <dbp-language-select + id="lang-select" + lang="${this.lang}"></dbp-language-select> </div> + <div class="hd1-middle"></div> <div class="hd1-right"> - <dbp-auth-menu-button subscribe="auth" class="auth-button" lang="${this.lang}"></dbp-auth-menu-button> + <dbp-auth-menu-button + subscribe="auth" + class="auth-button" + lang="${this.lang}"></dbp-auth-menu-button> </div> <div class="hd2-left"> <div class="header"> - <slot name="name">DBP<br />Digital Blueprint</slot> + <slot name="name"> + DBP + <br /> + Digital Blueprint + </slot> </div> </div> <div class="hd2-right"> <slot name="logo"> <div id="main-logo"> - <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="70" viewBox="0 0 13.197 11.828" xmlns:v="https://vecta.io/nano"><style><![CDATA[.B{fill:#c8c7c7}.C{fill:#231f20}]]></style><path d="M0 4.942v.313l5.866 3.295 5.927-3.295v-.313L5.896 8.237z" class="B"/><path d="M5.865 8.549l5.927-3.295v-.313L5.896 8.237z" class="C"/><path d="M0 6.581v.312l5.866 3.295 5.927-3.295v-.312L5.896 9.876z" class="B"/><path d="M5.865 10.188l5.927-3.295v-.312L5.896 9.876z" class="C"/><path d="M0 8.22v.313l5.866 3.295 5.927-3.295V8.22l-5.896 3.295z" class="B"/><path d="M5.865 11.827l5.927-3.295V8.22l-5.897 3.295z" class="C"/><path d="M8.844 4.991L7.37 4.167l1.474-.824 1.474.824z" class="B"/><use xlink:href="#B" class="C"/><path d="M8.774 3.295L7.3 2.471l1.474-.824 1.474.824z" fill="#656263"/><use xlink:href="#B" x="-1.474" y="0.823" class="C"/><use xlink:href="#B" x="-2.948" class="B"/><g fill="#7b7979"><use xlink:href="#B" x="-1.474" y="-0.824"/><use xlink:href="#B" x="-1.474" y="-2.471"/><path d="M4.422 2.471l-1.474-.824L4.422.823l1.474.824z"/></g><use xlink:href="#B" x="-4.422" y="-0.824" class="B"/><path d="M11.722 1.647L10.249.823 11.722 0l1.474.824z" class="C"/><g class="B"><path d="M8.844 6.589L7.37 5.766l1.474-.824 1.474.824z"/><use xlink:href="#B" y="1.647"/></g><use xlink:href="#B" x="-4.422" y="0.823" class="C"/><defs ><path id="B" d="M7.37 5.766l-1.474-.824 1.474-.824 1.474.824z"/></defs></svg> + <svg + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + height="70" + viewBox="0 0 13.197 11.828" + xmlns:v="https://vecta.io/nano"> + <style> + <![CDATA[.B{fill:#c8c7c7}.C{fill:#231f20}]]> + </style> + <path + d="M0 4.942v.313l5.866 3.295 5.927-3.295v-.313L5.896 8.237z" + class="B" /> + <path + d="M5.865 8.549l5.927-3.295v-.313L5.896 8.237z" + class="C" /> + <path + d="M0 6.581v.312l5.866 3.295 5.927-3.295v-.312L5.896 9.876z" + class="B" /> + <path + d="M5.865 10.188l5.927-3.295v-.312L5.896 9.876z" + class="C" /> + <path + d="M0 8.22v.313l5.866 3.295 5.927-3.295V8.22l-5.896 3.295z" + class="B" /> + <path + d="M5.865 11.827l5.927-3.295V8.22l-5.897 3.295z" + class="C" /> + <path + d="M8.844 4.991L7.37 4.167l1.474-.824 1.474.824z" + class="B" /> + <use xlink:href="#B" class="C" /> + <path + d="M8.774 3.295L7.3 2.471l1.474-.824 1.474.824z" + fill="#656263" /> + <use xlink:href="#B" x="-1.474" y="0.823" class="C" /> + <use xlink:href="#B" x="-2.948" class="B" /> + <g fill="#7b7979"> + <use xlink:href="#B" x="-1.474" y="-0.824" /> + <use xlink:href="#B" x="-1.474" y="-2.471" /> + <path + d="M4.422 2.471l-1.474-.824L4.422.823l1.474.824z" /> + </g> + <use xlink:href="#B" x="-4.422" y="-0.824" class="B" /> + <path + d="M11.722 1.647L10.249.823 11.722 0l1.474.824z" + class="C" /> + <g class="B"> + <path + d="M8.844 6.589L7.37 5.766l1.474-.824 1.474.824z" /> + <use xlink:href="#B" y="1.647" /> + </g> + <use xlink:href="#B" x="-4.422" y="0.823" class="C" /> + <defs> + <path + id="B" + d="M7.37 5.766l-1.474-.824 1.474-.824 1.474.824z" /> + </defs> + </svg> </div> </slot> </div> @@ -947,43 +1087,58 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { </header> <div id="headline"> <h1 class="title"> - <slot name="title"> - ${this.topicMetaDataText('name')} - </slot> + <slot name="title">${this.topicMetaDataText('name')}</slot> </h1> </div> <aside> <h2 class="subtitle" @click="${this.toggleMenu}"> ${this.subtitle} - <dbp-icon name="chevron-down" style="color: var(--dbp-accent)" id="menu-chevron-icon"></dbp-icon> + <dbp-icon + name="chevron-down" + style="color: var(--dbp-accent)" + id="menu-chevron-icon"></dbp-icon> </h2> <ul class="menu hidden"> ${menuTemplates} - <li class="close" @click="${this.hideMenu}"><dbp-icon name="close" style="color: var(--dbp-accent)"></dbp-icon></li> + <li class="close" @click="${this.hideMenu}"> + <dbp-icon name="close" style="color: var(--dbp-accent)"></dbp-icon> + </li> </ul> </aside> <main> - <div style="display: ${! this.metadata[this.activeView] ? 'block' : 'none'};"> + <div + style="display: ${!this.metadata[this.activeView] ? 'block' : 'none'};"> <h2>${i18n.t('page-not-found')}</h2> <p>${i18n.t('choose-from-menu')}</p> </div> <p class="description">${this.description}</p> - ${ this._renderActivity() } + ${this._renderActivity()} </main> <footer> <slot name="footer"> <slot name="footer-links"> - <a rel="noopener" class="" href="#use-your-privacy-policy-link">${i18n.t('privacy-policy')}</a> - <a rel="noopener" class="" href="#use-your-imprint-link">${i18n.t('imprint')}</a> - <a rel="noopener" class="" href="#use-your-imprint-link">${i18n.t('contact')}</a> + <a rel="noopener" class="" href="#use-your-privacy-policy-link"> + ${i18n.t('privacy-policy')} + </a> + <a rel="noopener" class="" href="#use-your-imprint-link"> + ${i18n.t('imprint')} + </a> + <a rel="noopener" class="" href="#use-your-imprint-link"> + ${i18n.t('contact')} + </a> </slot> - <dbp-build-info class="${prodClassMap}" git-info="${this.gitInfo}" env="${this.env}" build-url="${this.buildUrl}" build-time="${this.buildTime}"></dbp-build-info> + <dbp-build-info + class="${prodClassMap}" + git-info="${this.gitInfo}" + env="${this.env}" + build-url="${this.buildUrl}" + build-time="${this.buildTime}"></dbp-build-info> </slot> </footer> </div> </div> `; } -} \ No newline at end of file +} diff --git a/packages/app-shell/src/auth-menu-button.js b/packages/app-shell/src/auth-menu-button.js index 847d9cf0e0980a3efacf652afe242c138ce3248d..a0eb8e566d9bd82f7384ad5e0770e76dbf36ee88 100644 --- a/packages/app-shell/src/auth-menu-button.js +++ b/packages/app-shell/src/auth-menu-button.js @@ -4,11 +4,10 @@ import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {Icon} from '@dbp-toolkit/common'; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; -import {LoginStatus} from "@dbp-toolkit/auth/src/util"; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; +import {LoginStatus} from '@dbp-toolkit/auth/src/util'; export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { - constructor() { super(); this._i18n = createInstance(); @@ -28,8 +27,8 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, - auth: { type: Object }, + lang: {type: String}, + auth: {type: Object}, }; } @@ -55,7 +54,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { * We need to set the width manually because a percent width is in relation to the viewport */ updateDropdownWidth() { - const dropdown = this.shadowRoot.querySelector("div.dropdown-menu"); + const dropdown = this.shadowRoot.querySelector('div.dropdown-menu'); if (!dropdown) { return; @@ -63,7 +62,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { let viewportOffset = this.getBoundingClientRect(); let spaceToRIght = window.innerWidth - viewportOffset.left; - dropdown.setAttribute("style", `width: ${spaceToRIght - 20}px`); + dropdown.setAttribute('style', `width: ${spaceToRIght - 20}px`); } onLoginClicked(e) { @@ -77,7 +76,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -102,10 +101,12 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { display: block; } - input::-moz-focus-inner { border: 0; } + input::-moz-focus-inner { + border: 0; + } - :focus-visible{ - outline:none !important; + :focus-visible { + outline: none !important; outline-width: 0 !important; box-shadow: none; -moz-box-shadow: none; @@ -113,7 +114,8 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { box-shadow: 0px 0px 4px 2px var(--dbp-accent); } - .dropdown.is-active .dropdown-menu, .dropdown.is-hoverable:hover .dropdown-menu { + .dropdown.is-active .dropdown-menu, + .dropdown.is-hoverable:hover .dropdown-menu { display: block; } @@ -147,11 +149,11 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { background-color: var(--dbp-hover-base); } - .menu a.selected { - color: var(--dbp-secondary-text); - background-color: var(--dbp-secondary-base); + .menu a.selected { + color: var(--dbp-secondary-text); + background-color: var(--dbp-secondary-base); } - + .dropdown-item { color: var(--dbp-text-muted); display: block; @@ -224,13 +226,13 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { overflow: hidden; text-overflow: ellipsis; min-width: 0; - margin-right: 0.5em + margin-right: 0.5em; } `; } setChevron(name) { - const chevron = this.shadowRoot.querySelector("#menu-chevron-icon"); + const chevron = this.shadowRoot.querySelector('#menu-chevron-icon'); if (chevron !== null) { chevron.name = name; } @@ -239,7 +241,9 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { onDropdownClick(event) { event.stopPropagation(); event.currentTarget.classList.toggle('is-active'); - this.setChevron(event.currentTarget.classList.contains('is-active') ? 'chevron-up' : 'chevron-down'); + this.setChevron( + event.currentTarget.classList.contains('is-active') ? 'chevron-up' : 'chevron-down' + ); this.updateDropdownWidth(); } @@ -253,19 +257,24 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { renderLoggedIn() { const i18n = this._i18n; - + return html` <div class="dropdown" @click="${this.onDropdownClick}"> <a href="#"> <div class="dropdown-trigger login-button"> <div class="name">${this.auth['user-full-name']}</div> - <dbp-icon class="menu-icon" name="chevron-down" id="menu-chevron-icon"></dbp-icon> + <dbp-icon + class="menu-icon" + name="chevron-down" + id="menu-chevron-icon"></dbp-icon> </div> </a> <div class="dropdown-menu" id="dropdown-menu2" role="menu"> <div class="dropdown-content" @blur="${this.closeDropdown}"> <div class="menu"> - <a href="#" @click="${this.onLogoutClicked}" class="dropdown-item">${i18n.t('logout')}</a> + <a href="#" @click="${this.onLogoutClicked}" class="dropdown-item"> + ${i18n.t('logout')} + </a> </div> </div> </div> @@ -307,11 +316,9 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { } render() { - const loggedIn = (this.auth['login-status'] === 'logged-in'); + const loggedIn = this.auth['login-status'] === 'logged-in'; return html` - <div class="authbox"> - ${loggedIn ? this.renderLoggedIn() : this.renderLoggedOut()} - </div> + <div class="authbox">${loggedIn ? this.renderLoggedIn() : this.renderLoggedOut()}</div> `; } -} \ No newline at end of file +} diff --git a/packages/app-shell/src/build-info.js b/packages/app-shell/src/build-info.js index 375f3a1e6f34ffcfdb67bbd3bb74f30ed58d5ce3..f8a5e4e3e24fdebde0594157253d771be400d836 100644 --- a/packages/app-shell/src/build-info.js +++ b/packages/app-shell/src/build-info.js @@ -1,9 +1,8 @@ import {html, css} from 'lit'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; export class BuildInfo extends AdapterLitElement { - constructor() { super(); this.env = ''; @@ -15,10 +14,10 @@ export class BuildInfo extends AdapterLitElement { static get properties() { return { ...super.properties, - env: { type: String }, - buildUrl: { type: String, attribute: "build-url" }, - buildTime: { type: String, attribute: "build-time" }, - gitInfo: { type: String, attribute: "git-info" } + env: {type: String}, + buildUrl: {type: String, attribute: 'build-url'}, + buildTime: {type: String, attribute: 'build-time'}, + gitInfo: {type: String, attribute: 'git-info'}, }; } @@ -32,7 +31,7 @@ export class BuildInfo extends AdapterLitElement { display: inline-block; } `; - } + } render() { const date = new Date(this.buildTime); @@ -46,4 +45,4 @@ export class BuildInfo extends AdapterLitElement { </a> `; } -} \ No newline at end of file +} diff --git a/packages/app-shell/src/dbp-activity-example.js b/packages/app-shell/src/dbp-activity-example.js index aeb7c78fab7df83815bea2b3189924e3a457dad0..6c75ee4c48edb4a19e23148ed8b0747bde145110 100644 --- a/packages/app-shell/src/dbp-activity-example.js +++ b/packages/app-shell/src/dbp-activity-example.js @@ -1,9 +1,8 @@ -import {html , LitElement} from 'lit'; +import {html, LitElement} from 'lit'; import {createInstance} from './i18n.js'; import * as commonUtils from '@dbp-toolkit/common/utils'; class ActivityExample extends LitElement { - constructor() { super(); this._i18n = createInstance(); @@ -12,14 +11,14 @@ class ActivityExample extends LitElement { static get properties() { return { - lang: { type: String }, + lang: {type: String}, }; } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); break; } @@ -32,7 +31,14 @@ class ActivityExample extends LitElement { const i18n = this._i18n; return html` <h3>${i18n.t('activity-example.hello-world')}</h3> - <ul>${(Array.from(Array(100).keys())).map(i => html`<li>${i18n.t('activity-example.hello-world') + ' ' + i}</li>`)}</ul> + <ul> + ${Array.from(Array(100).keys()).map( + (i) => + html` + <li>${i18n.t('activity-example.hello-world') + ' ' + i}</li> + ` + )} + </ul> `; } } diff --git a/packages/app-shell/src/dbp-app-shell-welcome.js b/packages/app-shell/src/dbp-app-shell-welcome.js index 7339fb96bbd10f030b1c0330f6ea1c632ceb8198..98d92e43e36e017a2264d0936a5658e7e5450fc2 100644 --- a/packages/app-shell/src/dbp-app-shell-welcome.js +++ b/packages/app-shell/src/dbp-app-shell-welcome.js @@ -5,7 +5,6 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; class AppShellWelcome extends ScopedElementsMixin(LitElement) { - constructor() { super(); this._i18n = createInstance(); @@ -16,7 +15,7 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { static get properties() { return { - lang: { type: String }, + lang: {type: String}, }; } @@ -26,7 +25,7 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -35,14 +34,17 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { } static get styles() { - // language=css return css` ${commonStyles.getThemeCSS()} ${commonStyles.getGeneralCSS()} - p { line-height: 1.8em } - .item { padding-top: 0.5em;} + p { + line-height: 1.8em; + } + .item { + padding-top: 0.5em; + } .description { padding-left: 2em; font-style: italic; @@ -54,14 +56,14 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { color: var(--dbp-hover-text, var(--dbp-text)); background-color: var(--dbp-hover-base); } - + h2 a { cursor: pointer; text-decoration: none; } h2 a::after { - content: "\\00a0\\00a0"; + content: '\\00a0\\00a0'; background-color: var(--dbp-text); -webkit-mask-image: url('data:image/svg+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Ebene_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2014.8%2062.4%22%20style%3D%22enable-background%3Anew%200%200%2014.8%2062.4%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cg%20transform%3D%22translate%28-382.21%20-336.98%29%22%3E%0A%09%3Cg%3E%0A%09%09%3Cpath%20d%3D%22M383%2C380.5c-0.2%2C0-0.4-0.1-0.6-0.3c-0.3-0.3-0.3-0.8%2C0.1-1.1l12.5-10.9l-12.5-10.9c-0.3-0.3-0.4-0.8-0.1-1.1%0A%09%09%09c0.3-0.3%2C0.8-0.4%2C1.1-0.1l13.1%2C11.5c0.2%2C0.2%2C0.3%2C0.4%2C0.3%2C0.6s-0.1%2C0.5-0.3%2C0.6l-13.1%2C11.5C383.4%2C380.4%2C383.2%2C380.5%2C383%2C380.5z%22%2F%3E%0A%09%3C%2Fg%3E%0A%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A'); mask-image: url('data:image/svg+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Ebene_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2014.8%2062.4%22%20style%3D%22enable-background%3Anew%200%200%2014.8%2062.4%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cg%20transform%3D%22translate%28-382.21%20-336.98%29%22%3E%0A%09%3Cg%3E%0A%09%09%3Cpath%20d%3D%22M383%2C380.5c-0.2%2C0-0.4-0.1-0.6-0.3c-0.3-0.3-0.3-0.8%2C0.1-1.1l12.5-10.9l-12.5-10.9c-0.3-0.3-0.4-0.8-0.1-1.1%0A%09%09%09c0.3-0.3%2C0.8-0.4%2C1.1-0.1l13.1%2C11.5c0.2%2C0.2%2C0.3%2C0.4%2C0.3%2C0.6s-0.1%2C0.5-0.3%2C0.6l-13.1%2C11.5C383.4%2C380.4%2C383.2%2C380.5%2C383%2C380.5z%22%2F%3E%0A%09%3C%2Fg%3E%0A%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A'); @@ -74,10 +76,10 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { -webkit-mask-size: 100%; mask-size: 100%; } - - h2 a:hover::after { - background-color: var(--dbp-hover-text, var(--dbp-text)); - } + + h2 a:hover::after { + background-color: var(--dbp-hover-text, var(--dbp-text)); + } `; } _onVisibilityChanged() { @@ -111,39 +113,50 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { for (let routeName of app.visibleRoutes) { let data = app.metadata[routeName]; - if (routeName !== "welcome") { + if (routeName !== 'welcome') { itemTemplates.push(html` <div class="item"> - <h2><a href="#" @click=${(e) => {switchActivity(e, data);}}>${data.name[this.lang]}</a></h2> + <h2> + <a + href="#" + @click=${(e) => { + switchActivity(e, data); + }}> + ${data.name[this.lang]} + </a> + </h2> <p class="description">${data.description[this.lang]}</p> - </div>`); + </div> + `); } } return html` - <p>${i18n.t('welcome.headline', {appname: app.topic.name[this.lang]})} - ${app.topic.description[this.lang] }</p> - <br> + <p> + ${i18n.t('welcome.headline', {appname: app.topic.name[this.lang]})} + ${app.topic.description[this.lang]} + </p> + <br /> ${itemTemplates} `; } } export const appWelcomeMeta = { - "element": "dbp-app-shell-welcome", - "module_src": "", - "routing_name": "welcome", - "name": { - "de": "Willkommen", - "en": "Welcome" + element: 'dbp-app-shell-welcome', + module_src: '', + routing_name: 'welcome', + name: { + de: 'Willkommen', + en: 'Welcome', }, - "short_name": { - "de": "Willkommen", - "en": "Welcome" + short_name: { + de: 'Willkommen', + en: 'Welcome', }, - "description": { - "de": "Willkommen", - "en": "Welcome" + description: { + de: 'Willkommen', + en: 'Welcome', }, visible: true, required_roles: [], diff --git a/packages/app-shell/src/dbp-app-shell.js b/packages/app-shell/src/dbp-app-shell.js index beaa822b9cfad39f9080a6eb26260c3904bd19b6..266ed57bc6713b47371c234482191244c7c04944 100644 --- a/packages/app-shell/src/dbp-app-shell.js +++ b/packages/app-shell/src/dbp-app-shell.js @@ -1,4 +1,4 @@ import {AppShell} from './app-shell.js'; import * as commonUtils from '@dbp-toolkit/common/utils'; -commonUtils.defineCustomElement('dbp-app-shell', AppShell); \ No newline at end of file +commonUtils.defineCustomElement('dbp-app-shell', AppShell); diff --git a/packages/app-shell/src/i18n/de/translation.json b/packages/app-shell/src/i18n/de/translation.json index 0e2b2c9914db40c797438fe88a8a4a139ee355aa..4d0604ac07fc954917037c9936f693fc1063243f 100644 --- a/packages/app-shell/src/i18n/de/translation.json +++ b/packages/app-shell/src/i18n/de/translation.json @@ -1,22 +1,22 @@ { - "logo": { - "word1": "Wissen", - "word2": "Technik", - "word3": "Leidenschaft" - }, - "privacy-policy": "Datenschutz", - "imprint": "Impressum", - "contact": "Kontakt", - "page-updated-needs-reload": "Die Applikation wurde aktualisiert. Bitte laden Sie die Seite neu.", - "activity-example": { - "hello-world": "Hallo Welt" - }, - "welcome": { - "headline": "Willkommen bei der Applikation '{{appname}}'." - }, - "login": "Anmelden", - "logout": "Abmelden", - "page-not-found": "Die gewünschte Seite wurde nicht gefunden", - "choose-from-menu": "Bitte wählen Sie eine Aktivität aus dem Menu.", - "color-mode": "Farbmodus ändern" + "logo": { + "word1": "Wissen", + "word2": "Technik", + "word3": "Leidenschaft" + }, + "privacy-policy": "Datenschutz", + "imprint": "Impressum", + "contact": "Kontakt", + "page-updated-needs-reload": "Die Applikation wurde aktualisiert. Bitte laden Sie die Seite neu.", + "activity-example": { + "hello-world": "Hallo Welt" + }, + "welcome": { + "headline": "Willkommen bei der Applikation '{{appname}}'." + }, + "login": "Anmelden", + "logout": "Abmelden", + "page-not-found": "Die gewünschte Seite wurde nicht gefunden", + "choose-from-menu": "Bitte wählen Sie eine Aktivität aus dem Menu.", + "color-mode": "Farbmodus ändern" } diff --git a/packages/app-shell/src/i18n/en/translation.json b/packages/app-shell/src/i18n/en/translation.json index 3f94e35ce727eb9800c6b51599c53039fd01ed26..cc7544bd2093e44e397d71db63c5e919a87797b5 100644 --- a/packages/app-shell/src/i18n/en/translation.json +++ b/packages/app-shell/src/i18n/en/translation.json @@ -1,22 +1,22 @@ { - "logo": { - "word1": "Science", - "word2": "Passion", - "word3": "Technology" - }, - "privacy-policy": "Privacy Policy", - "imprint": "Legal Notice", - "contact": "Contact", - "page-updated-needs-reload": "The application has been updated. Please reload the page.", - "activity-example": { - "hello-world": "Hello World" - }, - "welcome": { - "headline": "Welcome to the '{{appname}}' application." - }, - "login": "Login", - "logout": "Logout", - "page-not-found": "Requested Page Not Found", - "choose-from-menu": "Please choose an activity from the menu.", - "color-mode": "Change color mode" + "logo": { + "word1": "Science", + "word2": "Passion", + "word3": "Technology" + }, + "privacy-policy": "Privacy Policy", + "imprint": "Legal Notice", + "contact": "Contact", + "page-updated-needs-reload": "The application has been updated. Please reload the page.", + "activity-example": { + "hello-world": "Hello World" + }, + "welcome": { + "headline": "Welcome to the '{{appname}}' application." + }, + "login": "Login", + "logout": "Logout", + "page-not-found": "Requested Page Not Found", + "choose-from-menu": "Please choose an activity from the menu.", + "color-mode": "Change color mode" } diff --git a/packages/app-shell/src/index.js b/packages/app-shell/src/index.js index e7ac96a3ddeb18382bbb3895a676dde23fbd1f17..125995a100cc050db2ad68f0351dbefd1ca99494 100644 --- a/packages/app-shell/src/index.js +++ b/packages/app-shell/src/index.js @@ -1,3 +1,3 @@ import {AppShell} from './app-shell.js'; -export {AppShell}; \ No newline at end of file +export {AppShell}; diff --git a/packages/app-shell/src/router.js b/packages/app-shell/src/router.js index e4ed40c081d714ca82d9ce70624d2a2adca8dbce..cbaefc12f3d6b60146482fbbb3c6dd5c74bed126 100644 --- a/packages/app-shell/src/router.js +++ b/packages/app-shell/src/router.js @@ -5,7 +5,6 @@ import generateUrls from 'universal-router/generateUrls'; * A wrapper around UniversalRouter which adds history integration */ export class Router { - /** * @param {Array} routes The routes passed to UniversalRouter * @param {object} options Options @@ -42,21 +41,24 @@ export class Router { setStateFromCurrentLocation() { const oldPathName = location.pathname; - this.router.resolve({pathname: oldPathName}).then(page => { - const newPathname = this.getPathname(page); - // In case of a router redirect, set the new location - if (newPathname !== oldPathName) { - const referrerUrl = location.href; - window.history.replaceState({}, '', newPathname); - this.dispatchLocationChanged(referrerUrl); - } else if (this.isBasePath(oldPathName)) { - page = this.getDefaultState(); - } - this.setState(page); - }).catch((e) => { - // In case we can't resolve the location, just leave things as is. - // This happens when a user enters a wrong URL or when testing with karma. - }); + this.router + .resolve({pathname: oldPathName}) + .then((page) => { + const newPathname = this.getPathname(page); + // In case of a router redirect, set the new location + if (newPathname !== oldPathName) { + const referrerUrl = location.href; + window.history.replaceState({}, '', newPathname); + this.dispatchLocationChanged(referrerUrl); + } else if (this.isBasePath(oldPathName)) { + page = this.getDefaultState(); + } + this.setState(page); + }) + .catch((e) => { + // In case we can't resolve the location, just leave things as is. + // This happens when a user enters a wrong URL or when testing with karma. + }); } isBasePath(pathname) { @@ -72,8 +74,7 @@ export class Router { setTimeout(() => { const newPathname = this.getPathname(); const oldPathname = location.pathname; - if (newPathname === oldPathname) - return; + if (newPathname === oldPathname) return; const defaultPathname = this.getPathname(this.getDefaultState()); if (newPathname === defaultPathname && this.isBasePath(oldPathname)) { @@ -92,16 +93,18 @@ export class Router { * @param {string} pathname */ updateFromPathname(pathname) { - this.router.resolve({pathname: pathname}).then(page => { - if (location.pathname === pathname) - return; - const referrerUrl = location.href; - window.history.pushState({}, '', pathname); - this.setState(page); - this.dispatchLocationChanged(referrerUrl); - }).catch((err) => { - throw new Error(`Route not found: ${pathname}: ${err}`); - }); + this.router + .resolve({pathname: pathname}) + .then((page) => { + if (location.pathname === pathname) return; + const referrerUrl = location.href; + window.history.pushState({}, '', pathname); + this.setState(page); + this.dispatchLocationChanged(referrerUrl); + }) + .catch((err) => { + throw new Error(`Route not found: ${pathname}: ${err}`); + }); } /** @@ -114,8 +117,7 @@ export class Router { */ getPathname(partialState) { const currentState = this.getState(); - if (partialState === undefined) - partialState = {}; + if (partialState === undefined) partialState = {}; let combined = {...currentState, ...partialState}; try { @@ -126,13 +128,15 @@ export class Router { } } - dispatchLocationChanged(referrerUrl = "") { + dispatchLocationChanged(referrerUrl = '') { // fire a locationchanged event - window.dispatchEvent(new CustomEvent('locationchanged', { - detail: { - referrerUrl: referrerUrl, - }, - bubbles: true - })); + window.dispatchEvent( + new CustomEvent('locationchanged', { + detail: { + referrerUrl: referrerUrl, + }, + bubbles: true, + }) + ); } } diff --git a/packages/app-shell/src/tugraz-logo.js b/packages/app-shell/src/tugraz-logo.js index 98641c958844a18ae2f4894b94de72c17e722c7e..2bad029b4cb9c95409892d7cdf041ae6cf33cce2 100644 --- a/packages/app-shell/src/tugraz-logo.js +++ b/packages/app-shell/src/tugraz-logo.js @@ -1,10 +1,9 @@ import {html, css} from 'lit'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {createInstance} from './i18n.js'; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; export class TUGrazLogo extends AdapterLitElement { - constructor() { super(); @@ -15,13 +14,13 @@ export class TUGrazLogo extends AdapterLitElement { static get properties() { return { ...super.properties, - lang: { type: String } + lang: {type: String}, }; } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -37,8 +36,7 @@ export class TUGrazLogo extends AdapterLitElement { display: inline-block; } - #claim - { + #claim { font-size: 12px; text-align: right; padding: 0 17px 0 0; @@ -54,15 +52,15 @@ export class TUGrazLogo extends AdapterLitElement { overflow: visible; } - a{ - display:block; + a { + display: block; } - * { - transition:fill 0.15s, stroke 0.15s; + * { + transition: fill 0.15s, stroke 0.15s; } `; - } + } render() { const i18n = this._i18n; @@ -73,8 +71,59 @@ export class TUGrazLogo extends AdapterLitElement { <div class="int-header-logo-claim-single">${i18n.t('logo.word2')}</div> <div class="int-header-logo-claim-single">${i18n.t('logo.word3')}</div> </div> - <svg id="img" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" height="51.862" width="141.1" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 141.10001 51.862499"><g transform="matrix(1.25 0 0 -1.25 0 51.862)"><g transform="scale(.1)"><path style="fill:#e4154b" d="m0 103.73h207.45v207.46l-207.45 0.01v-207.47z"></path><path style="fill:#e4154b" d="m228.19 103.73h207.46v207.46h-207.46v-207.46z"></path><path style="fill:#e4154b" d="m456.41 103.73h207.44v207.46h-207.44v-207.46z"></path><path style="fill:#e4154b" d="m103.72 0h207.47v207.46h-207.47v-207.46z"></path><path style="fill:#e4154b" d="m352.68 207.46h207.44v207.46h-207.44v-207.46z"></path><path style="fill:var(--dbp-base-inverted)" d="m751.04 277.91h-66.426v33.195h171.19v-33.195h-66.407v-173.73h-38.359v173.73"></path><path style="fill:var(--dbp-base-inverted)" d="m1048.3 180.22c0-12.461-2.25-23.711-6.72-33.75-4.5-10.039-10.61-18.555-18.36-25.567-7.76-7.031-16.9-12.421-27.503-16.21-10.605-3.809-22.109-5.7036-34.551-5.7036-12.422 0-23.945 1.8946-34.551 5.7036-10.605 3.789-19.824 9.179-27.656 16.21-7.851 7.012-13.984 15.528-18.34 25.567-4.394 10.039-6.582 21.289-6.582 33.75v130.89h38.379v-129.59c0-5.039 0.801-10.351 2.442-15.898 1.64-5.547 4.336-10.664 8.125-15.332s8.789-8.516 15.039-11.523c6.211-3.008 13.926-4.512 23.144-4.512 9.199 0 16.914 1.504 23.145 4.512 6.23 3.007 11.25 6.855 15.039 11.523 3.77 4.668 6.48 9.785 8.12 15.332 1.63 5.547 2.45 10.859 2.45 15.898v129.59h38.38v-130.89"></path><path style="fill:var(--dbp-base-inverted)" d="m832.56 75.664c-7.597 3.2812-17.46 4.8632-25.332 4.8632-22.929 0-35.605-14.434-35.605-33.184 0-18.613 12.383-32.637 33.34-32.637 5.351 0 9.59 0.5274 12.969 1.3086v23.867h-20.84v14.414h39.687v-49.297c-10.41-2.6172-21.25-4.707-31.816-4.707-31.797 0-53.906 14.805-53.906 45.742 0 31.348 20.566 48.906 53.906 48.906 11.406 0 20.41-1.4453 28.867-3.8086l-1.27-15.469"></path><path style="fill:var(--dbp-base-inverted)" d="m856.2 69.375h16.758v-15.332h0.293c0.84 6.289 8.574 16.914 19.824 16.914 1.836 0 3.828 0 5.782-0.5273v-17.715c-1.68 0.918-5.059 1.4454-8.457 1.4454-15.333 0-15.333-17.832-15.333-27.52v-24.785h-18.867v67.52"></path><path style="fill:var(--dbp-base-inverted)" d="m913.75 65.84c7.324 3.1446 17.187 5.1172 25.215 5.1172 22.09 0 31.23-8.5351 31.23-28.457v-8.6523c0-6.8165 0.156-11.934 0.293-16.914 0.137-5.1172 0.41-9.8242 0.84-15.078h-16.602c-0.703 3.5352-0.703 8.0078-0.839 10.098h-0.293c-4.36-7.4618-13.81-11.661-22.38-11.661-12.793 0-25.332 7.207-25.332 20.059 0 10.078 5.195 15.976 12.383 19.258 7.187 3.2812 16.464 3.9453 24.355 3.9453h10.41c0 10.879-5.195 14.551-16.328 14.551-8.008 0-16.035-2.8907-22.363-7.3438l-0.586 15.078zm22.11-52.715c5.782 0 10.274 2.3633 13.223 6.0352 3.105 3.8086 3.945 8.6523 3.945 13.906h-8.164c-8.437 0-20.957-1.3086-20.957-11.68 0-5.7617 5.195-8.2617 11.953-8.2617"></path><path style="fill:var(--dbp-base-inverted)" d="m985.69 69.375h57.422v-14.414l-36.04-39.473h37.31v-13.633h-60.235v14.297l36.715 39.59h-35.172v13.633"></path><path style="fill:#e4154b" d="m1059.6 0h69.102v69.121h-69.102v-69.121z"></path></g></g></svg> + <svg + id="img" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xml:space="preserve" + height="51.862" + width="141.1" + version="1.1" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/" + viewBox="0 0 141.10001 51.862499"> + <g transform="matrix(1.25 0 0 -1.25 0 51.862)"> + <g transform="scale(.1)"> + <path + style="fill:#e4154b" + d="m0 103.73h207.45v207.46l-207.45 0.01v-207.47z"></path> + <path + style="fill:#e4154b" + d="m228.19 103.73h207.46v207.46h-207.46v-207.46z"></path> + <path + style="fill:#e4154b" + d="m456.41 103.73h207.44v207.46h-207.44v-207.46z"></path> + <path + style="fill:#e4154b" + d="m103.72 0h207.47v207.46h-207.47v-207.46z"></path> + <path + style="fill:#e4154b" + d="m352.68 207.46h207.44v207.46h-207.44v-207.46z"></path> + <path + style="fill:var(--dbp-base-inverted)" + d="m751.04 277.91h-66.426v33.195h171.19v-33.195h-66.407v-173.73h-38.359v173.73"></path> + <path + style="fill:var(--dbp-base-inverted)" + d="m1048.3 180.22c0-12.461-2.25-23.711-6.72-33.75-4.5-10.039-10.61-18.555-18.36-25.567-7.76-7.031-16.9-12.421-27.503-16.21-10.605-3.809-22.109-5.7036-34.551-5.7036-12.422 0-23.945 1.8946-34.551 5.7036-10.605 3.789-19.824 9.179-27.656 16.21-7.851 7.012-13.984 15.528-18.34 25.567-4.394 10.039-6.582 21.289-6.582 33.75v130.89h38.379v-129.59c0-5.039 0.801-10.351 2.442-15.898 1.64-5.547 4.336-10.664 8.125-15.332s8.789-8.516 15.039-11.523c6.211-3.008 13.926-4.512 23.144-4.512 9.199 0 16.914 1.504 23.145 4.512 6.23 3.007 11.25 6.855 15.039 11.523 3.77 4.668 6.48 9.785 8.12 15.332 1.63 5.547 2.45 10.859 2.45 15.898v129.59h38.38v-130.89"></path> + <path + style="fill:var(--dbp-base-inverted)" + d="m832.56 75.664c-7.597 3.2812-17.46 4.8632-25.332 4.8632-22.929 0-35.605-14.434-35.605-33.184 0-18.613 12.383-32.637 33.34-32.637 5.351 0 9.59 0.5274 12.969 1.3086v23.867h-20.84v14.414h39.687v-49.297c-10.41-2.6172-21.25-4.707-31.816-4.707-31.797 0-53.906 14.805-53.906 45.742 0 31.348 20.566 48.906 53.906 48.906 11.406 0 20.41-1.4453 28.867-3.8086l-1.27-15.469"></path> + <path + style="fill:var(--dbp-base-inverted)" + d="m856.2 69.375h16.758v-15.332h0.293c0.84 6.289 8.574 16.914 19.824 16.914 1.836 0 3.828 0 5.782-0.5273v-17.715c-1.68 0.918-5.059 1.4454-8.457 1.4454-15.333 0-15.333-17.832-15.333-27.52v-24.785h-18.867v67.52"></path> + <path + style="fill:var(--dbp-base-inverted)" + d="m913.75 65.84c7.324 3.1446 17.187 5.1172 25.215 5.1172 22.09 0 31.23-8.5351 31.23-28.457v-8.6523c0-6.8165 0.156-11.934 0.293-16.914 0.137-5.1172 0.41-9.8242 0.84-15.078h-16.602c-0.703 3.5352-0.703 8.0078-0.839 10.098h-0.293c-4.36-7.4618-13.81-11.661-22.38-11.661-12.793 0-25.332 7.207-25.332 20.059 0 10.078 5.195 15.976 12.383 19.258 7.187 3.2812 16.464 3.9453 24.355 3.9453h10.41c0 10.879-5.195 14.551-16.328 14.551-8.008 0-16.035-2.8907-22.363-7.3438l-0.586 15.078zm22.11-52.715c5.782 0 10.274 2.3633 13.223 6.0352 3.105 3.8086 3.945 8.6523 3.945 13.906h-8.164c-8.437 0-20.957-1.3086-20.957-11.68 0-5.7617 5.195-8.2617 11.953-8.2617"></path> + <path + style="fill:var(--dbp-base-inverted)" + d="m985.69 69.375h57.422v-14.414l-36.04-39.473h37.31v-13.633h-60.235v14.297l36.715 39.59h-35.172v13.633"></path> + <path + style="fill:#e4154b" + d="m1059.6 0h69.102v69.121h-69.102v-69.121z"></path> + </g> + </g> + </svg> </a> `; } -} \ No newline at end of file +} diff --git a/packages/app-shell/test/unit.js b/packages/app-shell/test/unit.js index 6943d1c2a038b210326ea9a20714e9dd663e3671..f4b5deb64ae2df23694eb5f3be216f839e17ab62 100644 --- a/packages/app-shell/test/unit.js +++ b/packages/app-shell/test/unit.js @@ -3,28 +3,31 @@ import {assert} from '@esm-bundle/chai'; import {Router} from '../src/router.js'; suite('router', () => { + test('basics', () => { + const routes = [ + { + name: 'foo', + path: '', + action: (context) => { + return {}; + }, + }, + ]; - test('basics', () => { - const routes = [ - { - name: 'foo', - path: '', - action: (context) => { - return {}; - } - }, - ]; + const router = new Router(routes, { + routeName: 'foo', + getState: () => { + return {}; + }, + setState: (state) => {}, + getDefaultState: () => { + return {}; + }, + }); - const router = new Router(routes, { - routeName: 'foo', - getState: () => { return {}; }, - setState: (state) => { }, - getDefaultState: () => { return {}; }, + router.setStateFromCurrentLocation(); + router.update(); + router.updateFromPathname('/'); + assert.equal(router.getPathname(), '/'); }); - - router.setStateFromCurrentLocation(); - router.update(); - router.updateFromPathname("/"); - assert.equal(router.getPathname(), '/'); - }); -}); \ No newline at end of file +}); diff --git a/packages/auth/.eslintrc.json b/packages/auth/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/auth/.eslintrc.json +++ b/packages/auth/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/auth/.prettierignore b/packages/auth/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..9f6b5e8e183caf09d6144a683354474d673c1337 --- /dev/null +++ b/packages/auth/.prettierignore @@ -0,0 +1,2 @@ +node_modules/ +/dist \ No newline at end of file diff --git a/packages/auth/.prettierrc.json b/packages/auth/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/auth/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/auth/i18next-scanner.config.js b/packages/auth/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/auth/i18next-scanner.config.js +++ b/packages/auth/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/auth/package.json b/packages/auth/package.json index 0cde8e8b0b074a00297068adfdfbc181fd4254ce..145fdcabcb3cac71ef60b73c7ca09ee26a229931 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,59 +1,63 @@ { - "name": "@dbp-toolkit/auth", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/auth", - "version": "0.2.6", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/auth" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-replace": "^3.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "glob": "^7.1.6", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/common": "^0.2.12", - "@open-wc/scoped-elements": "^2.0.0", - "event-target-shim": "^6.0.0", - "lit": "^2.0.0" - }, - "scripts": { - "clean": "rm dist/*", - "build": "yarn 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": "yarn run watch-local", - "watch-local": "rollup -c --watch", - "watch-dev": "rollup -c --watch --environment BUILD:development", - "test": "yarn run build-test && karma start --singleRun", - "lint": "eslint ." - } + "name": "@dbp-toolkit/auth", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/auth", + "version": "0.2.6", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/auth" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-replace": "^3.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "glob": "^7.1.6", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/common": "^0.2.12", + "@open-wc/scoped-elements": "^2.0.0", + "event-target-shim": "^6.0.0", + "lit": "^2.0.0" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "build": "yarn 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": "yarn run watch-local", + "watch-local": "rollup -c --watch", + "watch-dev": "rollup -c --watch --environment BUILD:development", + "test": "yarn run build-test && karma start --singleRun", + "lint": "eslint ." + } } diff --git a/packages/auth/rollup.config.js b/packages/auth/rollup.config.js index ecc3df3cbbed68e01d1911f517624721a05b2a14..d5f81517a1fc2599230a347d73ab23b8878d4308 100644 --- a/packages/auth/rollup.config.js +++ b/packages/auth/rollup.config.js @@ -2,43 +2,51 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build != 'test') ? ['src/dbp-auth.js', 'src/dbp-auth-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-auth.js', 'src/dbp-auth-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, {src: 'assets/silent-check-sso.html', dest: 'dist'}, {src: 'assets/favicon.ico', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/auth/src/auth-keycloak.js b/packages/auth/src/auth-keycloak.js index 643b33bb2d2aa0a76da4435948032171174c2e8d..db3ded9d87f5e8ef128ce5a3c0867f7d06a12164 100644 --- a/packages/auth/src/auth-keycloak.js +++ b/packages/auth/src/auth-keycloak.js @@ -1,9 +1,8 @@ import {createInstance} from './i18n.js'; import JSONLD from '@dbp-toolkit/common/jsonld'; -import {KeycloakWrapper} from './keycloak.js'; +import {KeycloakWrapper} from './keycloak.js'; import {LoginStatus} from './util.js'; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; - +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; /** * Keycloak auth web component @@ -20,13 +19,13 @@ export class AuthKeycloak extends AdapterLitElement { constructor() { super(); this.forceLogin = false; - this.token = ""; - this.subject = ""; - this.name = ""; + this.token = ''; + this.subject = ''; + this.name = ''; this.tryLogin = false; this.entryPointUrl = ''; this._user = null; - this._userId = ""; + this._userId = ''; this._authenticated = false; this._loginStatus = LoginStatus.UNKNOWN; this.requestedLoginStatus = LoginStatus.UNKNOWN; @@ -50,17 +49,17 @@ export class AuthKeycloak extends AdapterLitElement { switch (propName) { case 'lang': this._i18n.changeLanguage(this.lang); - break; + break; case 'entryPointUrl': // for preloading the instance JSONLD.getInstance(this.entryPointUrl, this.lang); - break; + break; case 'requestedLoginStatus': - console.log("requested-login-status changed", this.requestedLoginStatus); - switch(this.requestedLoginStatus) { + console.log('requested-login-status changed', this.requestedLoginStatus); + switch (this.requestedLoginStatus) { case LoginStatus.LOGGED_IN: this._kcwrapper.login({lang: this.lang, scope: this.scope || ''}); - break; + break; case LoginStatus.LOGGED_OUT: // Keycloak will redirect right away without emitting events, so we have // to do this manually here @@ -73,9 +72,9 @@ export class AuthKeycloak extends AdapterLitElement { if (this._loginStatus === LoginStatus.LOGGING_OUT) { this._setLoginStatus(LoginStatus.LOGGED_IN); } - break; + break; } - break; + break; } }); @@ -87,16 +86,16 @@ export class AuthKeycloak extends AdapterLitElement { jsonld = await JSONLD.getInstance(this.entryPointUrl, this.lang); let baseUrl = ''; try { - baseUrl = jsonld.getApiUrlForEntityName("FrontendUser"); - } catch(error) { + baseUrl = jsonld.getApiUrlForEntityName('FrontendUser'); + } catch (error) { // backwards compat - baseUrl = jsonld.getApiUrlForEntityName("Person"); + baseUrl = jsonld.getApiUrlForEntityName('Person'); } const apiUrl = baseUrl + '/' + encodeURIComponent(userId); let response = await fetch(apiUrl, { headers: { - 'Authorization': 'Bearer ' + this.token, + Authorization: 'Bearer ' + this.token, }, }); if (!response.ok) { @@ -114,13 +113,13 @@ export class AuthKeycloak extends AdapterLitElement { this._authenticated = kc.authenticated; if (kc.authenticated) { - let tokenChanged = (this.token !== kc.token); + let tokenChanged = this.token !== kc.token; this.name = kc.idTokenParsed.name; this.token = kc.token; this.subject = kc.subject; const userId = kc.idTokenParsed.preferred_username; - let userChanged = (userId !== this._userId); + let userChanged = userId !== this._userId; if (userChanged) { this._userId = userId; let user; @@ -144,10 +143,10 @@ export class AuthKeycloak extends AdapterLitElement { if (this._loginStatus === LoginStatus.LOGGED_IN) { this._setLoginStatus(LoginStatus.LOGGING_OUT); } - this.name = ""; - this.token = ""; - this.subject = ""; - this._userId = ""; + this.name = ''; + this.token = ''; + this.subject = ''; + this._userId = ''; this._user = null; this._setLoginStatus(LoginStatus.LOGGED_OUT); @@ -157,13 +156,13 @@ export class AuthKeycloak extends AdapterLitElement { sendSetPropertyEvents() { const auth = { 'login-status': this._loginStatus, - 'subject': this.subject, - 'token': this.token, + subject: this.subject, + token: this.token, 'user-full-name': this.name, 'user-id': this._userId, // Deprecated 'person-id': this._userId, - 'person': this._user, + person: this._user, }; // inject a window.DBPAuth variable for cypress @@ -175,8 +174,7 @@ export class AuthKeycloak extends AdapterLitElement { } _setLoginStatus(status, force) { - if (this._loginStatus === status && !force) - return; + if (this._loginStatus === status && !force) return; this._loginStatus = status; this.sendSetPropertyEvents(); @@ -185,36 +183,39 @@ export class AuthKeycloak extends AdapterLitElement { static get properties() { return { ...super.properties, - lang: { type: String }, - forceLogin: { type: Boolean, attribute: 'force-login' }, - tryLogin: { type: Boolean, attribute: 'try-login' }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - name: { type: String, attribute: false }, - token: { type: String, attribute: false }, - subject: { type: String, attribute: false }, - _userId: { type: String, attribute: false }, - _user: { type: Object, attribute: false }, - _loginStatus: { type: String, attribute: false }, - keycloakUrl: { type: String, attribute: 'url' }, - realm: { type: String }, - clientId: { type: String, attribute: 'client-id' }, - silentCheckSsoRedirectUri: { type: String, attribute: 'silent-check-sso-redirect-uri' }, - scope: { type: String }, - idpHint: { type: String, attribute: 'idp-hint' }, - requestedLoginStatus: { type: String, attribute: 'requested-login-status' }, + lang: {type: String}, + forceLogin: {type: Boolean, attribute: 'force-login'}, + tryLogin: {type: Boolean, attribute: 'try-login'}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + name: {type: String, attribute: false}, + token: {type: String, attribute: false}, + subject: {type: String, attribute: false}, + _userId: {type: String, attribute: false}, + _user: {type: Object, attribute: false}, + _loginStatus: {type: String, attribute: false}, + keycloakUrl: {type: String, attribute: 'url'}, + realm: {type: String}, + clientId: {type: String, attribute: 'client-id'}, + silentCheckSsoRedirectUri: {type: String, attribute: 'silent-check-sso-redirect-uri'}, + scope: {type: String}, + idpHint: {type: String, attribute: 'idp-hint'}, + requestedLoginStatus: {type: String, attribute: 'requested-login-status'}, }; } connectedCallback() { super.connectedCallback(); - if (!this.keycloakUrl) - throw Error("url not set"); - if (!this.realm) - throw Error("realm not set"); - if (!this.clientId) - throw Error("client-id not set"); - this._kcwrapper = new KeycloakWrapper(this.keycloakUrl, this.realm, this.clientId, this.silentCheckSsoRedirectUri, this.idpHint); + if (!this.keycloakUrl) throw Error('url not set'); + if (!this.realm) throw Error('realm not set'); + if (!this.clientId) throw Error('client-id not set'); + this._kcwrapper = new KeycloakWrapper( + this.keycloakUrl, + this.realm, + this.clientId, + this.silentCheckSsoRedirectUri, + this.idpHint + ); this._kcwrapper.addEventListener('changed', this._onKCChanged); const handleLogin = async () => { @@ -241,4 +242,4 @@ export class AuthKeycloak extends AdapterLitElement { super.disconnectedCallback(); } -} \ No newline at end of file +} diff --git a/packages/auth/src/dbp-auth-demo.js b/packages/auth/src/dbp-auth-demo.js index 7cedb8ca9fecec369f46b602e1cbc5bd09fa39dd..c3d4de877d7d14a1cf0ce413d8badd7539ebacdc 100644 --- a/packages/auth/src/dbp-auth-demo.js +++ b/packages/auth/src/dbp-auth-demo.js @@ -5,7 +5,7 @@ import {AuthKeycloak} from './auth-keycloak.js'; import {LoginButton} from './login-button.js'; import * as commonUtils from '@dbp-toolkit/common/utils'; //import {name as pkgName} from './../package.json'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; export class DbpAuthDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { @@ -19,24 +19,24 @@ export class DbpAuthDemo extends ScopedElementsMixin(DBPLitElement) { static get scopedElements() { return { - 'dbp-auth-keycloak': AuthKeycloak, - 'dbp-login-button': LoginButton, + 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-login-button': LoginButton, }; } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - auth: { type: Object }, - noAuth: { type: Boolean, attribute: 'no-auth' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + auth: {type: Object}, + noAuth: {type: Boolean, attribute: 'no-auth'}, }; } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -47,21 +47,20 @@ export class DbpAuthDemo extends ScopedElementsMixin(DBPLitElement) { async _onUserInfoClick() { const div = this._('#person-info'); if (!this.auth.token) { - console.error("not logged in"); - div.innerHTML = "You are not logged in!"; + console.error('not logged in'); + div.innerHTML = 'You are not logged in!'; return; } - let userInfoURL = 'https://auth-dev.tugraz.at/auth/realms/tugraz-vpu/protocol/openid-connect/userinfo'; + let userInfoURL = + 'https://auth-dev.tugraz.at/auth/realms/tugraz-vpu/protocol/openid-connect/userinfo'; // NOTE: the URL and realm need to match the keycloak config above - const response = await fetch( - userInfoURL, { - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer ' + this.auth.token - } - } - ); + const response = await fetch(userInfoURL, { + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer ' + this.auth.token, + }, + }); const person = await response.json(); console.log(person); div.innerHTML = JSON.stringify(person); @@ -70,8 +69,8 @@ export class DbpAuthDemo extends ScopedElementsMixin(DBPLitElement) { async _onShowToken() { const div = this._('#token-info'); if (!this.auth.token) { - console.error("not logged in"); - div.innerHTML = "You are not logged in!"; + console.error('not logged in'); + div.innerHTML = 'You are not logged in!'; return; } @@ -80,29 +79,44 @@ export class DbpAuthDemo extends ScopedElementsMixin(DBPLitElement) { } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button>` : html` - <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/silent-check-sso.html" - url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" - client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> - <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> - </div> - `; + return this.noAuth + ? html` + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + ` + : html` + <div class="container"> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + silent-check-sso-redirect-uri="/silent-check-sso.html" + url="https://auth-dev.tugraz.at/auth" + realm="tugraz-vpu" + client-id="auth-dev-mw-frontend-local" + try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + </div> + `; } render() { return html` <style> - /* from BULMA.CSS */ + /* from BULMA.CSS */ .section { - padding: 3rem 1.5rem; - font-family: sans-serif; + padding: 3rem 1.5rem; + font-family: sans-serif; } .content h1 { font-size: 2em; - margin-bottom: .5em; + margin-bottom: 0.5em; } - .content h1, .content h2, .content h3, .content h4, .content h5, .content h6 { + .content h1, + .content h2, + .content h3, + .content h4, + .content h5, + .content h6 { color: var(--dbp-text); font-weight: 600; line-height: 1.125; @@ -118,8 +132,8 @@ export class DbpAuthDemo extends ScopedElementsMixin(DBPLitElement) { </div> ${this.getAuthComponentHtml()} <div class="container"> - <input type="button" value="Fetch userinfo" @click="${this._onUserInfoClick}"> - <input type="button" value="Show token" @click="${this._onShowToken}"> + <input type="button" value="Fetch userinfo" @click="${this._onUserInfoClick}" /> + <input type="button" value="Show token" @click="${this._onShowToken}" /> <h4>Person info:</h4> <div id="person-info"></div> <h4>Token info:</h4> diff --git a/packages/auth/src/i18n.js b/packages/auth/src/i18n.js index fbc1b032f3c662e149547117a8df129be5262e99..fe81f7a9df229aa43f2a7467e5a0012883de0a87 100644 --- a/packages/auth/src/i18n.js +++ b/packages/auth/src/i18n.js @@ -7,4 +7,4 @@ export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); } -export {setOverrides}; \ No newline at end of file +export {setOverrides}; diff --git a/packages/auth/src/i18n/de/translation.json b/packages/auth/src/i18n/de/translation.json index 08be5c27c8d1109c3b70a4726305dc8aa661e5c4..1fa9113346b481be1aa1110c85aebe59a152cc5a 100644 --- a/packages/auth/src/i18n/de/translation.json +++ b/packages/auth/src/i18n/de/translation.json @@ -1,4 +1,4 @@ { - "login": "Anmelden", - "logout": "Abmelden" + "login": "Anmelden", + "logout": "Abmelden" } diff --git a/packages/auth/src/i18n/en/translation.json b/packages/auth/src/i18n/en/translation.json index 8c6f4faa8e8bb80ca74065918f431b01140f16a8..8bfc42ac59dd49d3e115f2a8668a582e0028c255 100644 --- a/packages/auth/src/i18n/en/translation.json +++ b/packages/auth/src/i18n/en/translation.json @@ -1,4 +1,4 @@ { - "login": "Login", - "logout": "Logout" + "login": "Login", + "logout": "Logout" } diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js index c2fe4ab023069ba2337d73f1f0aa1a3d9e7866da..8280af461188918a90d4791b02bc387c9807bbec 100644 --- a/packages/auth/src/index.js +++ b/packages/auth/src/index.js @@ -1,4 +1,4 @@ import {AuthKeycloak} from './auth-keycloak.js'; import {LoginButton} from './login-button.js'; -export {AuthKeycloak, LoginButton}; \ No newline at end of file +export {AuthKeycloak, LoginButton}; diff --git a/packages/auth/src/keycloak.js b/packages/auth/src/keycloak.js index f2382a33ffa74e5f5df688e4f3a001a08b68f32f..50b25d8f65f356bf6152bdd2141f022c016cd43e 100644 --- a/packages/auth/src/keycloak.js +++ b/packages/auth/src/keycloak.js @@ -1,5 +1,4 @@ -import {EventTarget} from "event-target-shim"; // Because EventTarget() doesn't exist on Safari - +import {EventTarget} from 'event-target-shim'; // Because EventTarget() doesn't exist on Safari /** * Imports the keycloak JS API as if it was a module. @@ -10,35 +9,29 @@ async function importKeycloak(baseUrl) { const keycloakSrc = baseUrl + '/js/keycloak.min.js'; // Importing will write it to window so we take it from there await import(keycloakSrc); - if (importKeycloak._keycloakMod !== undefined) - return importKeycloak._keycloakMod; + if (importKeycloak._keycloakMod !== undefined) return importKeycloak._keycloakMod; importKeycloak._keycloakMod = window.Keycloak; delete window.Keycloak; return importKeycloak._keycloakMod; } - -const promiseTimeout = function(ms, promise) { +const promiseTimeout = function (ms, promise) { let timeout = new Promise((resolve, reject) => { - let id = setTimeout(() => { - clearTimeout(id); - reject('Timed out in '+ ms + 'ms.'); - }, ms); + let id = setTimeout(() => { + clearTimeout(id); + reject('Timed out in ' + ms + 'ms.'); + }, ms); }); - return Promise.race([ - promise, - timeout - ]); + return Promise.race([promise, timeout]); }; - /** * Returns a URL for a relative path or URL * * @param {string} urlOrPath */ -const ensureURL = function(urlOrPath) { +const ensureURL = function (urlOrPath) { try { return new URL(urlOrPath).href; } catch (e) { @@ -46,15 +39,13 @@ const ensureURL = function(urlOrPath) { } }; - /** * Wraps the keycloak API to support async/await, adds auto token refreshing and consolidates all * events into one native "changed" event - * + * * The "changed" event has the real keycloak instance as "detail" */ export class KeycloakWrapper extends EventTarget { - constructor(baseURL, realm, clientId, silentCheckSsoUri, idpHint) { super(); @@ -77,36 +68,35 @@ export class KeycloakWrapper extends EventTarget { this.DEBUG = false; this._onVisibilityChanged = this._onVisibilityChanged.bind(this); - document.addEventListener("visibilitychange", this._onVisibilityChanged); + document.addEventListener('visibilitychange', this._onVisibilityChanged); } /** * This needs to be called or the instance will leak; */ close() { - document.removeEventListener("visibilitychange", this._onVisibilityChanged); + document.removeEventListener('visibilitychange', this._onVisibilityChanged); } _onVisibilityChanged() { - let isVisible = (document.visibilityState === 'visible'); + let isVisible = document.visibilityState === 'visible'; if (isVisible && this._keycloak.authenticated) { this._checkTokeHasExpired(); } } _onChanged() { - const event = new CustomEvent("changed", { + const event = new CustomEvent('changed', { detail: this._keycloak, bubbles: true, - composed: true + composed: true, }); this.dispatchEvent(event); } _onReady(authenticated) { // Avoid emitting changed when nothing has changed on init() - if (authenticated) - this._onChanged(); + if (authenticated) this._onChanged(); } async _onTokenExpired() { @@ -121,7 +111,7 @@ export class KeycloakWrapper extends EventTarget { return; } - console.assert(refreshed, "token should have been refreshed"); + console.assert(refreshed, 'token should have been refreshed'); } async _checkTokeHasExpired() { @@ -137,8 +127,7 @@ export class KeycloakWrapper extends EventTarget { console.log('Failed to refresh the token', error); } - if (this.DEBUG && refreshed) - console.log("token has been refreshed"); + if (this.DEBUG && refreshed) console.log('token has been refreshed'); } async _onAuthSuccess() { @@ -148,7 +137,10 @@ export class KeycloakWrapper extends EventTarget { clearInterval(this._checkId); this._checkId = null; } - this._checkId = setInterval(this._checkTokeHasExpired.bind(this), this.CHECK_INTERVAL * 1000); + this._checkId = setInterval( + this._checkTokeHasExpired.bind(this), + this.CHECK_INTERVAL * 1000 + ); this._onChanged(); } @@ -163,8 +155,7 @@ export class KeycloakWrapper extends EventTarget { } async _ensureInstance() { - if (this._keycloak !== null) - return; + if (this._keycloak !== null) return; const Keycloak = await importKeycloak(this._baseURL); @@ -195,8 +186,7 @@ export class KeycloakWrapper extends EventTarget { async _ensureInit() { await this._ensureInstance(); - if (this._initDone) - return; + if (this._initDone) return; this._initDone = true; const options = { @@ -209,7 +199,6 @@ export class KeycloakWrapper extends EventTarget { } if (this._silentCheckSsoUri) { - options['onLoad'] = 'check-sso'; options['silentCheckSsoRedirectUri'] = ensureURL(this._silentCheckSsoUri); @@ -222,7 +211,6 @@ export class KeycloakWrapper extends EventTarget { } else { await this._keycloakInit(options); } - } /** @@ -230,7 +218,7 @@ export class KeycloakWrapper extends EventTarget { */ isLoggingIn() { const href = window.location.href; - return (href.search('[&#]state=') >= 0 && href.search('[&#]session_state=') >= 0); + return href.search('[&#]state=') >= 0 && href.search('[&#]session_state=') >= 0; } /** @@ -248,7 +236,7 @@ export class KeycloakWrapper extends EventTarget { if (!this._keycloak.authenticated) { await this._keycloak.login({ - kcLocale: language, // Keycloak < 9.0 + kcLocale: language, // Keycloak < 9.0 locale: language, scope: scope, idpHint: this._idpHint, @@ -278,4 +266,4 @@ export class KeycloakWrapper extends EventTarget { await this._ensureInit(); this._keycloak.logout(); } -} \ No newline at end of file +} diff --git a/packages/auth/src/login-button.js b/packages/auth/src/login-button.js index 7b4caa2a6beb9aaa5334ca404fa5738dba564293..6cb968e27c1ba91785627ce3e3e688fb496bd43e 100644 --- a/packages/auth/src/login-button.js +++ b/packages/auth/src/login-button.js @@ -52,7 +52,6 @@ let loginSVG = ` `; export class LoginButton extends ScopedElementsMixin(AdapterLitElement) { - constructor() { super(); this._i18n = createInstance(); @@ -68,8 +67,8 @@ export class LoginButton extends ScopedElementsMixin(AdapterLitElement) { static get properties() { return { - lang: { type: String }, - auth: { type: Object }, + lang: {type: String}, + auth: {type: Object}, }; } @@ -93,7 +92,7 @@ export class LoginButton extends ScopedElementsMixin(AdapterLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -106,48 +105,50 @@ export class LoginButton extends ScopedElementsMixin(AdapterLitElement) { return [ commonStyles.getThemeCSS(), css` - :host { - display: inline-block; - } - - a { - color: var(--dbp-text); - fill: var(--dbp-text); - cursor: pointer; - text-decoration: none; - } - - .login-box { - display: flex; - align-items: center; - padding: 0.3em 0.4em; - transition: background-color 0.15s, color 0.15s; - } - - .login-box svg, .icon { - width: 1.1em; - height: 1.1em; - } - - .login-box svg, .spinner { - display: flex; - } - - .login-box:hover svg path { - fill: var(--dbp-hover-text); - } - - .login-box:hover { - color: var(--dbp-hover-text); - background-color: var(--dbp-hover-base); - cursor: pointer; - transition: none; - } - - .login-box .label { - padding-left: 0.2em; - } - ` + :host { + display: inline-block; + } + + a { + color: var(--dbp-text); + fill: var(--dbp-text); + cursor: pointer; + text-decoration: none; + } + + .login-box { + display: flex; + align-items: center; + padding: 0.3em 0.4em; + transition: background-color 0.15s, color 0.15s; + } + + .login-box svg, + .icon { + width: 1.1em; + height: 1.1em; + } + + .login-box svg, + .spinner { + display: flex; + } + + .login-box:hover svg path { + fill: var(--dbp-hover-text); + } + + .login-box:hover { + color: var(--dbp-hover-text); + background-color: var(--dbp-hover-base); + cursor: pointer; + transition: none; + } + + .login-box .label { + padding-left: 0.2em; + } + `, ]; } @@ -158,7 +159,9 @@ export class LoginButton extends ScopedElementsMixin(AdapterLitElement) { return html` <a href="#"> <div class="login-box login-button"> - <div class="icon"><dbp-mini-spinner class="spinner"></dbp-mini-spinner></div> + <div class="icon"> + <dbp-mini-spinner class="spinner"></dbp-mini-spinner> + </div> <div class="label">​</div> </div> </a> @@ -183,4 +186,4 @@ export class LoginButton extends ScopedElementsMixin(AdapterLitElement) { `; } } -} \ No newline at end of file +} diff --git a/packages/auth/test/unit.js b/packages/auth/test/unit.js index c7729814a4d34aed2ebf444d773e650717e546cd..4799db8bdcd5702d04795b7794ea71e4ad7a5671 100644 --- a/packages/auth/test/unit.js +++ b/packages/auth/test/unit.js @@ -4,58 +4,58 @@ import '../src/dbp-auth'; import '../src/dbp-auth-demo'; suite('dbp-auth basics', () => { - let node; - - setup(async () => { - node = document.createElement('dbp-auth-keycloak'); - node.setAttribute('url', 'someurl'); - node.setAttribute('realm', 'somerealm'); - node.setAttribute('client-id', 'someId'); - document.body.appendChild(node); - await node.updateComplete; - }); - - teardown(() => { - node.remove(); - }); - - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + let node; + + setup(async () => { + node = document.createElement('dbp-auth-keycloak'); + node.setAttribute('url', 'someurl'); + node.setAttribute('realm', 'somerealm'); + node.setAttribute('client-id', 'someId'); + document.body.appendChild(node); + await node.updateComplete; + }); + + teardown(() => { + node.remove(); + }); + + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); suite('dbp-login-button', () => { let node; - + setup(async () => { - node = document.createElement('dbp-login-button'); - document.body.appendChild(node); - await node.updateComplete; + node = document.createElement('dbp-login-button'); + document.body.appendChild(node); + await node.updateComplete; }); teardown(() => { - node.remove(); + node.remove(); }); - + test('should render', () => { assert.isNotNull(node.shadowRoot); }); - }); +}); suite('dbp-auth-demo basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-auth-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-auth-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/check-in-place-select/.eslintrc.json b/packages/check-in-place-select/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/check-in-place-select/.eslintrc.json +++ b/packages/check-in-place-select/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/check-in-place-select/.prettierignore b/packages/check-in-place-select/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/check-in-place-select/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/check-in-place-select/.prettierrc.json b/packages/check-in-place-select/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/check-in-place-select/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/check-in-place-select/i18next-scanner.config.js b/packages/check-in-place-select/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/check-in-place-select/i18next-scanner.config.js +++ b/packages/check-in-place-select/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/check-in-place-select/package.json b/packages/check-in-place-select/package.json index 934eb16d680762af0b80da07da38cd23d299ce6a..1108ce0f1c7d854097b7a72b8c99bbff0087a13c 100644 --- a/packages/check-in-place-select/package.json +++ b/packages/check-in-place-select/package.json @@ -1,60 +1,64 @@ { - "name": "@dbp-toolkit/check-in-place-select", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/check-in-place-select", - "version": "0.2.3", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/check-in-place-select" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-replace": "^3.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "jquery": "^3.4.1", - "lit": "^2.0.0", - "select2": "^4.0.10" - }, - "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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/check-in-place-select", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/check-in-place-select", + "version": "0.2.3", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/check-in-place-select" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-replace": "^3.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "jquery": "^3.4.1", + "lit": "^2.0.0", + "select2": "^4.0.10" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/check-in-place-select/rollup.config.js b/packages/check-in-place-select/rollup.config.js index 7a3aadb0071ddb99ce1788a77fb8968e1853fa0e..7749b3f15a4bff490f2e7a76ed0942200686e153 100644 --- a/packages/check-in-place-select/rollup.config.js +++ b/packages/check-in-place-select/rollup.config.js @@ -2,49 +2,55 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url" +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build != 'test') ? ['src/dbp-check-in-place-select.js', 'src/dbp-check-in-place-select-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-check-in-place-select.js', 'src/dbp-check-in-place-select-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), url({ limit: 0, - include: [ - await getPackagePath('select2', '**/*.css'), - ], + include: [await getPackagePath('select2', '**/*.css')], emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/check-in-place-select/src/check-in-place-select.js b/packages/check-in-place-select/src/check-in-place-select.js index 14e3385bae0c108ce6f93ae55276ea711f9e1cd0..0b60dc86db8e1b7862ea96d8961c99a605e6e0e7 100644 --- a/packages/check-in-place-select/src/check-in-place-select.js +++ b/packages/check-in-place-select/src/check-in-place-select.js @@ -9,19 +9,16 @@ import {Icon} from '@dbp-toolkit/common'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import select2CSSPath from 'select2/dist/css/select2.min.css'; -import * as errorUtils from "@dbp-toolkit/common/error"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; - +import * as errorUtils from '@dbp-toolkit/common/error'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; const checkInPlaceContext = { - "@id": "@id", - "name": "http://schema.org/name", - "maximumPhysicalAttendeeCapacity": "http://schema.org/maximumPhysicalAttendeeCapacity" + '@id': '@id', + name: 'http://schema.org/name', + maximumPhysicalAttendeeCapacity: 'http://schema.org/maximumPhysicalAttendeeCapacity', }; - export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { - constructor() { super(); Object.assign(CheckInPlaceSelect.prototype, errorUtils.errorMixin); @@ -48,37 +45,36 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { static get scopedElements() { return { - 'dbp-icon': Icon, + 'dbp-icon': Icon, }; } $(selector) { - if (typeof selector === "string") + if (typeof selector === 'string') return this._jquery(this.shadowRoot.querySelector(selector)); - else - return this._jquery(selector); + else return this._jquery(selector); } static get properties() { return { ...super.properties, - lang: { type: String }, - active: { type: Boolean, attribute: false }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - value: { type: String }, - object: { type: Object, attribute: false }, - showReloadButton: { type: Boolean, attribute: 'show-reload-button' }, - reloadButtonTitle: { type: String, attribute: 'reload-button-title' }, - showCapacity: { type: Boolean, attribute: 'show-capacity' }, - auth: { type: Object }, + lang: {type: String}, + active: {type: Boolean, attribute: false}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + value: {type: String}, + object: {type: Object, attribute: false}, + showReloadButton: {type: Boolean, attribute: 'show-reload-button'}, + reloadButtonTitle: {type: String, attribute: 'reload-button-title'}, + showCapacity: {type: Boolean, attribute: 'show-capacity'}, + auth: {type: Object}, }; } clear() { this.object = null; - this.$(this).attr("data-object", ""); - this.$(this).attr("value", ""); - this.$(this).data("object", null); + this.$(this).attr('data-object', ''); + this.$(this).attr('value', ''); + this.$(this).data('object', null); this.$select.val(null).trigger('change').trigger('select2:unselect'); } @@ -106,10 +102,9 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { } _onDocumentClicked(event) { - if (event.composedPath().includes(this)) - return; + if (event.composedPath().includes(this)) return; const $select = this.$('#' + this.selectId); - console.assert($select.length, "select2 missing"); + console.assert($select.length, 'select2 missing'); if (this.select2IsInitialized($select)) { $select.select2('close'); } @@ -118,14 +113,24 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { initJSONLD(ignorePreset = false) { const that = this; - JSONLD.getInstance(this.entryPointUrl).then(function (jsonld) { - that.jsonld = jsonld; - that.active = true; + JSONLD.getInstance(this.entryPointUrl).then( + function (jsonld) { + that.jsonld = jsonld; + that.active = true; - // we need to poll because maybe the user interface isn't loaded yet - // Note: we need to call initSelect2() in a different function so we can access "this" inside initSelect2() - commonUtils.pollFunc(() => { return that.initSelect2(ignorePreset); }, 10000, 100); - }, {}, this.lang); + // we need to poll because maybe the user interface isn't loaded yet + // Note: we need to call initSelect2() in a different function so we can access "this" inside initSelect2() + commonUtils.pollFunc( + () => { + return that.initSelect2(ignorePreset); + }, + 10000, + 100 + ); + }, + {}, + this.lang + ); } /** @@ -142,7 +147,7 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { } // find the correct api url for a checkInPlace - const apiUrl = this.jsonld.getApiUrlForIdentifier("http://schema.org/Place"); + const apiUrl = this.jsonld.getApiUrlForIdentifier('http://schema.org/Place'); // const apiUrl = this.jsonld.getApiUrlForEntityName("CheckInPlace"); if (this.$select === null) { @@ -156,86 +161,98 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { this.$select.off('select2:closing'); } - this.$select.select2({ - width: '100%', - language: this.lang === "de" ? select2LangDe() : select2LangEn(), - minimumInputLength: 2, - placeholder: this._i18n.t('check-in-place-select.placeholder'), - dropdownParent: this.$('#check-in-place-select-dropdown'), - ajax: { - delay: 500, - url: apiUrl, - contentType: "application/ld+json", - beforeSend: function (jqXHR) { - jqXHR.setRequestHeader('Authorization', 'Bearer ' + that.auth.token); - that.isSearching = true; - }, - data: function (params) { - return { - search: params.term.trim(), - }; - }, - processResults: function (data) { - that.$('#check-in-place-select-dropdown').addClass('select2-bug'); - - that.lastResult = data; - let transformed = that.jsonld.transformMembers(data, checkInPlaceContext); - const results = []; - transformed.forEach((place) => { - results.push({id: place["@id"], maximumPhysicalAttendeeCapacity: place["maximumPhysicalAttendeeCapacity"], text: that.generateOptionText(place)}); - }); - - return { - results: results - }; + this.$select + .select2({ + width: '100%', + language: this.lang === 'de' ? select2LangDe() : select2LangEn(), + minimumInputLength: 2, + placeholder: this._i18n.t('check-in-place-select.placeholder'), + dropdownParent: this.$('#check-in-place-select-dropdown'), + ajax: { + delay: 500, + url: apiUrl, + contentType: 'application/ld+json', + beforeSend: function (jqXHR) { + jqXHR.setRequestHeader('Authorization', 'Bearer ' + that.auth.token); + that.isSearching = true; + }, + data: function (params) { + return { + search: params.term.trim(), + }; + }, + processResults: function (data) { + that.$('#check-in-place-select-dropdown').addClass('select2-bug'); + + that.lastResult = data; + let transformed = that.jsonld.transformMembers(data, checkInPlaceContext); + const results = []; + transformed.forEach((place) => { + results.push({ + id: place['@id'], + maximumPhysicalAttendeeCapacity: + place['maximumPhysicalAttendeeCapacity'], + text: that.generateOptionText(place), + }); + }); + + return { + results: results, + }; + }, + error: (jqXHR, textStatus, errorThrown) => { + this.handleXhrError(jqXHR, textStatus, errorThrown); + }, + complete: (jqXHR, textStatus) => { + that.isSearching = false; + }, }, - error: (jqXHR, textStatus, errorThrown) => { this.handleXhrError(jqXHR, textStatus, errorThrown); }, - complete: (jqXHR, textStatus) => { - that.isSearching = false; + }) + .on('select2:open', function (e) { + const selectId = e.target.id; + + that.$( + ".select2-search__field[aria-controls='select2-" + selectId + "-results']" + ).each(function (key, value) { + value.focus(); + }); + }) + .on('select2:select', function (e) { + that.$('#check-in-place-select-dropdown').removeClass('select2-bug'); + // set custom element attributes + const identifier = e.params.data.id; + const maxCapacity = e.params.data.maximumPhysicalAttendeeCapacity; + that.object = findObjectInApiResults(identifier, that.lastResult); + + const room = that.object.identifier; + + $this.attr('data-object', JSON.stringify(that.object)); + $this.data('object', that.object); + const roomName = that.object.name; + + if ($this.attr('value') !== identifier) { + that.ignoreValueUpdate = true; + $this.attr('value', identifier); + + // fire a change event + that.dispatchEvent( + new CustomEvent('change', { + detail: { + value: identifier, + capacity: maxCapacity, + room: room, + name: roomName, + }, + bubbles: true, + }) + ); + } + }) + .on('select2:closing', (e) => { + if (that.isSearching) { + e.preventDefault(); } - } - }).on("select2:open", function (e) { - const selectId = e.target.id; - - that.$(".select2-search__field[aria-controls='select2-" + selectId + "-results']").each(function ( - key, - value, - ) { - value.focus(); }); - }).on("select2:select", function (e) { - that.$('#check-in-place-select-dropdown').removeClass('select2-bug'); - // set custom element attributes - const identifier = e.params.data.id; - const maxCapacity = e.params.data.maximumPhysicalAttendeeCapacity; - that.object = findObjectInApiResults(identifier, that.lastResult); - - const room = that.object.identifier; - - $this.attr("data-object", JSON.stringify(that.object)); - $this.data("object", that.object); - const roomName = that.object.name; - - if ($this.attr("value") !== identifier) { - that.ignoreValueUpdate = true; - $this.attr("value", identifier); - - // fire a change event - that.dispatchEvent(new CustomEvent('change', { - detail: { - value: identifier, - capacity: maxCapacity, - room: room, - name: roomName, - }, - bubbles: true - })); - } - }).on("select2:closing", (e) => { - if (that.isSearching) { - e.preventDefault(); - } - }); // TODO: doesn't work here // this.$('.select2-selection__arrow').click(() => { @@ -249,51 +266,66 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { fetch(apiUrl, { headers: { 'Content-Type': 'application/ld+json', - 'Authorization': 'Bearer ' + this.auth.token, + Authorization: 'Bearer ' + this.auth.token, }, }) - .then(result => { - if (!result.ok) throw result; - return result.json(); - }) - .then((place) => { - that.object = place; - const transformed = that.jsonld.compactMember(that.jsonld.expandMember(place), checkInPlaceContext); - const identifier = transformed["@id"]; - const maxCapacity = transformed["maximumPhysicalAttendeeCapacity"]; - const roomName = transformed["name"]; - const room = place.identifier; - - const option = new Option(that.generateOptionText(transformed), identifier, true, true); - $this.attr("data-object", JSON.stringify(place)); - $this.data("object", place); - that.$select.append(option).trigger('change'); - - // fire a change event - that.dispatchEvent(new CustomEvent('change', { - detail: { - value: identifier, - capacity: maxCapacity, - room: room, - name: roomName, - }, - bubbles: true - })); - }).catch((e) => { - console.log(e); - that.clear(); - }); + .then((result) => { + if (!result.ok) throw result; + return result.json(); + }) + .then((place) => { + that.object = place; + const transformed = that.jsonld.compactMember( + that.jsonld.expandMember(place), + checkInPlaceContext + ); + const identifier = transformed['@id']; + const maxCapacity = transformed['maximumPhysicalAttendeeCapacity']; + const roomName = transformed['name']; + const room = place.identifier; + + const option = new Option( + that.generateOptionText(transformed), + identifier, + true, + true + ); + $this.attr('data-object', JSON.stringify(place)); + $this.data('object', place); + that.$select.append(option).trigger('change'); + + // fire a change event + that.dispatchEvent( + new CustomEvent('change', { + detail: { + value: identifier, + capacity: maxCapacity, + room: room, + name: roomName, + }, + bubbles: true, + }) + ); + }) + .catch((e) => { + console.log(e); + that.clear(); + }); } return true; } generateOptionText(place) { - let text = place["name"]; + let text = place['name']; // add maximum capacity to checkInPlace if present - if (this.showCapacity && (place["maximumPhysicalAttendeeCapacity"] !== undefined) && (place["maximumPhysicalAttendeeCapacity"] !== null)) { - let capacity = place["maximumPhysicalAttendeeCapacity"]; + if ( + this.showCapacity && + place['maximumPhysicalAttendeeCapacity'] !== undefined && + place['maximumPhysicalAttendeeCapacity'] !== null + ) { + let capacity = place['maximumPhysicalAttendeeCapacity']; text += ` (${capacity})`; } @@ -303,7 +335,7 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); if (this.select2IsInitialized()) { @@ -311,14 +343,14 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { this.initSelect2(true); } break; - case "value": + case 'value': if (!this.ignoreValueUpdate && this.select2IsInitialized()) { this.initSelect2(); } this.ignoreValueUpdate = false; break; - case "entryPointUrl": + case 'entryPointUrl': // we don't need to preset the selector if the entry point url changes this.initJSONLD(true); break; @@ -329,7 +361,7 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { } select2IsInitialized() { - return this.$select !== null && this.$select.hasClass("select2-hidden-accessible"); + return this.$select !== null && this.$select.hasClass('select2-hidden-accessible'); } reloadClick() { @@ -338,12 +370,14 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { } // fire a change event - this.dispatchEvent(new CustomEvent('change', { - detail: { - value: this.value, - }, - bubbles: true - })); + this.dispatchEvent( + new CustomEvent('change', { + detail: { + value: this.value, + }, + bubbles: true, + }) + ); } static get styles() { @@ -354,38 +388,38 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { commonStyles.getFormAddonsCSS(), commonStyles.getSelect2CSS(), css` - .select2-control.control { - width: 100%; - } + .select2-control.control { + width: 100%; + } - .field .button.control { - display: flex; - align-items: center; - justify-content: center; - border: var(--dbp-border); - border-color: var(--dbp-text-muted); - -moz-border-radius-topright: var(--dbp-border-radius); - -moz-border-radius-bottomright: var(--dbp-border-radius); - line-height: 100%; - } + .field .button.control { + display: flex; + align-items: center; + justify-content: center; + border: var(--dbp-border); + border-color: var(--dbp-text-muted); + -moz-border-radius-topright: var(--dbp-border-radius); + -moz-border-radius-bottomright: var(--dbp-border-radius); + line-height: 100%; + } - .field .button.control dbp-icon { - top: 0; - } + .field .button.control dbp-icon { + top: 0; + } - input { - border-radius: 0; - } - - input[type="search"] { - -webkit-appearance: none; - } + input { + border-radius: 0; + } - /* https://github.com/select2/select2/issues/5457 */ - .select2-bug .loading-results { - display: none !important; - } - ` + input[type='search'] { + -webkit-appearance: none; + } + + /* https://github.com/select2/select2/issues/5457 */ + .select2-bug .loading-results { + display: none !important; + } + `, ]; } @@ -393,7 +427,7 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { const select2CSS = commonUtils.getAssetURL(select2CSSPath); const i18n = this._i18n; return html` - <link rel="stylesheet" href="${select2CSS}"> + <link rel="stylesheet" href="${select2CSS}" /> <style> #${this.selectId} { width: 100%; @@ -404,14 +438,27 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { <div class="field has-addons"> <div class="select2-control control"> <!-- https://select2.org--> - <select id="${this.selectId}" name="check-in-place" class="select" ?disabled=${!this.active}>${!this.active ? html`<option value="" disabled selected>${ i18n.t('check-in-place-select.login-required')}</option>` : ''}</select> + <select + id="${this.selectId}" + name="check-in-place" + class="select" + ?disabled=${!this.active}> + ${!this.active + ? html` + <option value="" disabled selected> + ${i18n.t('check-in-place-select.login-required')} + </option> + ` + : ''} + </select> </div> - <a class="control button" - id="reload-button" - ?disabled=${this.object === null} - @click="${this.reloadClick}" - style="display: ${this.showReloadButton ? "flex" : "none"}" - title="${this.reloadButtonTitle}"> + <a + class="control button" + id="reload-button" + ?disabled=${this.object === null} + @click="${this.reloadClick}" + style="display: ${this.showReloadButton ? 'flex' : 'none'}" + title="${this.reloadButtonTitle}"> <dbp-icon name="reload"></dbp-icon> </a> </div> @@ -419,4 +466,4 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { </div> `; } -} \ No newline at end of file +} diff --git a/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js b/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js index 6e4d1bef94ae34b17df436d6b18f03fe9cbae9ff..abb4b10d46e56dee2d753f670b7b1f75adf6f27c 100644 --- a/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js +++ b/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js @@ -4,10 +4,9 @@ import {CheckInPlaceSelect} from './check-in-place-select.js'; import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; import {createInstance} from './i18n.js'; - export class CheckInPlaceSelectDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); @@ -19,18 +18,18 @@ export class CheckInPlaceSelectDemo extends ScopedElementsMixin(DBPLitElement) { static get scopedElements() { return { - 'dbp-login-button': LoginButton, - 'dbp-check-in-place-select': CheckInPlaceSelect, - 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-login-button': LoginButton, + 'dbp-check-in-place-select': CheckInPlaceSelect, + 'dbp-auth-keycloak': AuthKeycloak, }; } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - noAuth: { type: Boolean, attribute: 'no-auth' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + noAuth: {type: Boolean, attribute: 'no-auth'}, }; } @@ -44,21 +43,35 @@ export class CheckInPlaceSelectDemo extends ScopedElementsMixin(DBPLitElement) { commonStyles.getThemeCSS(), commonStyles.getGeneralCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} - ` + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } + `, ]; } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button>` : html` - <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" - url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" - client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> - <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> - </div> - `; + return this.noAuth + ? html` + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + ` + : html` + <div class="container"> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + url="https://auth-dev.tugraz.at/auth" + realm="tugraz-vpu" + client-id="auth-dev-mw-frontend-local" + try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + </div> + `; } render() { @@ -73,13 +86,21 @@ export class CheckInPlaceSelectDemo extends ScopedElementsMixin(DBPLitElement) { <div class="field"> <label class="label">Check-In-Place 1</label> <div class="control"> - <dbp-check-in-place-select lang="${this.lang}" entry-point-url="${this.entryPointUrl}" subscribe="auth"></dbp-check-in-place-select> + <dbp-check-in-place-select + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + subscribe="auth"></dbp-check-in-place-select> </div> </div> <div class="field"> <label class="label">Check-In-Place 2</label> <div class="control"> - <dbp-check-in-place-select lang="${this.lang}" entry-point-url="${this.entryPointUrl}" subscribe="auth" show-reload-button reload-button-title="Click me"></dbp-check-in-place-select> + <dbp-check-in-place-select + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + subscribe="auth" + show-reload-button + reload-button-title="Click me"></dbp-check-in-place-select> </div> </div> </form> diff --git a/packages/check-in-place-select/src/i18n.js b/packages/check-in-place-select/src/i18n.js index fbc1b032f3c662e149547117a8df129be5262e99..fe81f7a9df229aa43f2a7467e5a0012883de0a87 100644 --- a/packages/check-in-place-select/src/i18n.js +++ b/packages/check-in-place-select/src/i18n.js @@ -7,4 +7,4 @@ export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); } -export {setOverrides}; \ No newline at end of file +export {setOverrides}; diff --git a/packages/check-in-place-select/src/i18n/de/select2.js b/packages/check-in-place-select/src/i18n/de/select2.js index bef156f0f506c91c494fa5fc1c7a7b49a8a97d9c..14d5c25e6b1a6b686274710751da7bbe72aa6c0b 100644 --- a/packages/check-in-place-select/src/i18n/de/select2.js +++ b/packages/check-in-place-select/src/i18n/de/select2.js @@ -15,7 +15,11 @@ export default function () { inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; - return 'Bitte ' + remainingChars + ' Zeichen mehr eingeben, es kann nach mehreren Teilen von Namen gesucht werden'; + return ( + 'Bitte ' + + remainingChars + + ' Zeichen mehr eingeben, es kann nach mehreren Teilen von Namen gesucht werden' + ); }, loadingMore: function () { return 'Lade mehr Ergebnisse…'; @@ -41,6 +45,6 @@ export default function () { }, removeAllItems: function () { return 'Entferne alle Gegenstände'; - } + }, }; } diff --git a/packages/check-in-place-select/src/i18n/de/translation.json b/packages/check-in-place-select/src/i18n/de/translation.json index d1ff788578d8e22855ee2d10af1b33a4018d438a..1ed905e7f798542238b033692c570d8233db50d4 100644 --- a/packages/check-in-place-select/src/i18n/de/translation.json +++ b/packages/check-in-place-select/src/i18n/de/translation.json @@ -1,6 +1,6 @@ { - "check-in-place-select": { - "placeholder": "Z.B. \"P1\", \"Rechbauerstraße\", \"PZ2EG048\"", - "login-required": "Anmeldung erforderlich" - } + "check-in-place-select": { + "placeholder": "Z.B. \"P1\", \"Rechbauerstraße\", \"PZ2EG048\"", + "login-required": "Anmeldung erforderlich" + } } diff --git a/packages/check-in-place-select/src/i18n/en/select2.js b/packages/check-in-place-select/src/i18n/en/select2.js index d172d72ef06e17651dda4d2f6d73ef49e50cf845..c6ff8f0a2febdf95de10ae02155e2337ca4e13c5 100644 --- a/packages/check-in-place-select/src/i18n/en/select2.js +++ b/packages/check-in-place-select/src/i18n/en/select2.js @@ -21,7 +21,10 @@ export default function () { inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; - var message = 'Please enter ' + remainingChars + ' or more characters, you can also search for multiple parts of names'; + var message = + 'Please enter ' + + remainingChars + + ' or more characters, you can also search for multiple parts of names'; return message; }, @@ -45,6 +48,6 @@ export default function () { }, removeAllItems: function () { return 'Remove all items'; - } + }, }; } diff --git a/packages/check-in-place-select/src/i18n/en/translation.json b/packages/check-in-place-select/src/i18n/en/translation.json index 40dc94b22cf850aa5fcdba65ce14784e0e25f839..f27540f2930e830162c9d2a556263efa70428dcf 100644 --- a/packages/check-in-place-select/src/i18n/en/translation.json +++ b/packages/check-in-place-select/src/i18n/en/translation.json @@ -1,6 +1,6 @@ { - "check-in-place-select": { - "placeholder": "E.g. \"P1\", \"Rechbauerstraße\", \"PZ2EG048\"", - "login-required": "Login required" - } + "check-in-place-select": { + "placeholder": "E.g. \"P1\", \"Rechbauerstraße\", \"PZ2EG048\"", + "login-required": "Login required" + } } diff --git a/packages/check-in-place-select/src/index.js b/packages/check-in-place-select/src/index.js index 0bbe1832a2891a709d78f0b8d421834606f6f0b4..0d0165e1bdb61d97b145ac6248df0e992f54341c 100644 --- a/packages/check-in-place-select/src/index.js +++ b/packages/check-in-place-select/src/index.js @@ -1,3 +1,3 @@ import {CheckInPlaceSelect} from './check-in-place-select.js'; -export {CheckInPlaceSelect}; \ No newline at end of file +export {CheckInPlaceSelect}; diff --git a/packages/check-in-place-select/src/utils.js b/packages/check-in-place-select/src/utils.js index 97d072d913ec7441ed76a704dc8658458ca0773b..167646f3b0ca2e9b656a3381e35e0b393d023e26 100644 --- a/packages/check-in-place-select/src/utils.js +++ b/packages/check-in-place-select/src/utils.js @@ -1,4 +1,3 @@ - /** * Finds an object in a JSON result by identifier * @@ -6,14 +5,14 @@ * @param results * @param identifierAttribute */ -export const findObjectInApiResults = (identifier, results, identifierAttribute = "@id") => { - const members = results["hydra:member"]; +export const findObjectInApiResults = (identifier, results, identifierAttribute = '@id') => { + const members = results['hydra:member']; if (members === undefined) { return; } - for (const object of members){ + for (const object of members) { if (object[identifierAttribute] === identifier) { return object; } diff --git a/packages/check-in-place-select/test/unit.js b/packages/check-in-place-select/test/unit.js index 9c8605e6e11ab9f059f1154041bb8fe8b247749e..8dd2b5307439a3a18395c4196c53fe35d6482147 100644 --- a/packages/check-in-place-select/test/unit.js +++ b/packages/check-in-place-select/test/unit.js @@ -4,37 +4,37 @@ import '../src/dbp-check-in-place-select.js'; import '../src/demo.js'; suite('dbp-check-in-place-select basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-check-in-place-select'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-check-in-place-select'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); suite('dbp-check-in-place-select-demo basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-check-in-place-select-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-check-in-place-select-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/common/.eslintrc.json b/packages/common/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/common/.eslintrc.json +++ b/packages/common/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/common/.prettierignore b/packages/common/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/common/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/common/.prettierrc.json b/packages/common/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/common/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/common/components.js b/packages/common/components.js index df6735311826455fca23614f2122047777259ea6..6a42c6afc7809394b9e260abd2f512b61ddec743 100644 --- a/packages/common/components.js +++ b/packages/common/components.js @@ -1,5 +1,13 @@ -import * as commonUtils from "./utils"; -import {Button, Icon, InlineNotification, LoadingButton, MiniSpinner, Spinner, Translated} from "./index"; +import * as commonUtils from './utils'; +import { + Button, + Icon, + InlineNotification, + LoadingButton, + MiniSpinner, + Spinner, + Translated, +} from './index'; commonUtils.defineCustomElement('dbp-mini-spinner', MiniSpinner); commonUtils.defineCustomElement('dbp-spinner', Spinner); diff --git a/packages/common/dbp-common-demo.js b/packages/common/dbp-common-demo.js index 5b5b2ad38126675bd502790353d7f3fa6973266d..c644cc9ff0f29678920e997b088056d6bc37d262 100644 --- a/packages/common/dbp-common-demo.js +++ b/packages/common/dbp-common-demo.js @@ -3,7 +3,16 @@ import {css, html, LitElement} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from './utils.js'; import * as commonStyles from './styles.js'; -import {getIconCSS, Icon, MiniSpinner, Button, LoadingButton, Spinner, InlineNotification, Translated} from './index.js'; +import { + getIconCSS, + Icon, + MiniSpinner, + Button, + LoadingButton, + Spinner, + InlineNotification, + Translated, +} from './index.js'; export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { constructor() { @@ -33,8 +42,8 @@ export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { static get properties() { return { - lang: { type: String }, - noAuth: { type: Boolean, attribute: 'no-auth' }, + lang: {type: String}, + noAuth: {type: Boolean, attribute: 'no-auth'}, }; } @@ -42,17 +51,20 @@ export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { super.connectedCallback(); this._i18n.changeLanguage(this.lang); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { // language=css return css` - ${ commonStyles.getThemeCSS() } + ${commonStyles.getThemeCSS()} - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } a:hover { color: #ffbb00 !important; @@ -67,15 +79,20 @@ export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { padding: 0px 0px 0px 3px; } - /* from BULMA.CSS */ + /* from BULMA.CSS */ .section { - padding: 3rem 1.5rem; + padding: 3rem 1.5rem; } .content h1 { font-size: 2em; - margin-bottom: .5em; + margin-bottom: 0.5em; } - .content h1, .content h2, .content h3, .content h4, .content h5, .content h6 { + .content h1, + .content h2, + .content h3, + .content h4, + .content h5, + .content h6 { color: var(--dbp-text); font-weight: 600; line-height: 1.125; @@ -87,11 +104,13 @@ export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { } getAuthComponentHtml() { - return this.noAuth ? html`` : html` - <div class="container"> - <dbp-auth lang="${this.lang}"></dbp-auth> - </div> - `; + return this.noAuth + ? html`` + : html` + <div class="container"> + <dbp-auth lang="${this.lang}"></dbp-auth> + </div> + `; } buttonClickHandler() { @@ -113,7 +132,7 @@ export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { return html` <style> a:after { - ${ getIconCSS('envelope') }; + ${getIconCSS('envelope')}; } </style> <section class="section"> @@ -139,23 +158,60 @@ export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { <div class="content"> <h2>Icons</h2> <div class="control"> - <p style="text-decoration: underline">Foo <dbp-icon name="cloudnetwork"></dbp-icon> bar</p> - <p style="font-size: 2em;">Foo <dbp-icon name="cloudnetwork"></dbp-icon> bar</p> - <p style="font-size: 2em; color: orange">Foo <dbp-icon name="cloudnetwork"></dbp-icon> bar</p> - <span style="background-color: #000"><a href="#" style=" color: #fff">foobar</a></span> - <p style="font-size: 2em; color: orange">Foo <dbp-icon name="information"></dbp-icon> bar</p> - <br> - - ${(new Array(100).fill(0)).map(i => html`<dbp-icon style="color: green; width: 50px; height: 50px; border: #000 solid 1px"name="happy"></dbp-icon>`)} + <p style="text-decoration: underline"> + Foo + <dbp-icon name="cloudnetwork"></dbp-icon> + bar + </p> + <p style="font-size: 2em;"> + Foo + <dbp-icon name="cloudnetwork"></dbp-icon> + bar + </p> + <p style="font-size: 2em; color: orange"> + Foo + <dbp-icon name="cloudnetwork"></dbp-icon> + bar + </p> + <span style="background-color: #000"> + <a href="#" style=" color: #fff">foobar</a> + </span> + <p style="font-size: 2em; color: orange"> + Foo + <dbp-icon name="information"></dbp-icon> + bar + </p> + <br /> + + ${new Array(100).fill(0).map( + (i) => + html` + <dbp-icon + style="color: green; width: 50px; height: 50px; border: #000 solid 1px" + name="happy"></dbp-icon> + ` + )} </div> </div> <div class="content"> <h2>Button</h2> <div class="control"> - <dbp-button value="Load" @click="${this.buttonClickHandler}" type="is-primary"></dbp-button> + <dbp-button + value="Load" + @click="${this.buttonClickHandler}" + type="is-primary"></dbp-button> - <dbp-loading-button @click="${this.loadingButtonClickHandler}" type="is-primary">Loading Button</dbp-loading-button> - <dbp-loading-button @click="${this.loadingButtonClickHandler}" type="is-primary" disabled>Loading Button Disabled</dbp-loading-button> + <dbp-loading-button + @click="${this.loadingButtonClickHandler}" + type="is-primary"> + Loading Button + </dbp-loading-button> + <dbp-loading-button + @click="${this.loadingButtonClickHandler}" + type="is-primary" + disabled> + Loading Button Disabled + </dbp-loading-button> </div> </div> <div class="content"> @@ -195,16 +251,33 @@ html { --dbp-override-primary-dark: green; /* Same for all other variables, prefix with "override" */ } -</style></pre> +</style></pre + > </div> <div class="content"> <h2>Inline Notification</h2> <div class="control"> - <dbp-inline-notification body="Item <b>foo</b> was deleted!" type="primary"></dbp-inline-notification><br> - <dbp-inline-notification summary="Item foo was deleted."></dbp-inline-notification><br> - <dbp-inline-notification summary="Item deleted" body="Item <b>foo</b> was deleted!" type="success"></dbp-inline-notification><br> - <dbp-inline-notification summary="Item deleted" body="Item <b>foo</b> was deleted!" type="danger"></dbp-inline-notification><br> - <dbp-inline-notification summary="Item deleted" body="Item <b>foo</b> was deleted!" type="warning"></dbp-inline-notification> + <dbp-inline-notification + body="Item <b>foo</b> was deleted!" + type="primary"></dbp-inline-notification> + <br /> + <dbp-inline-notification + summary="Item foo was deleted."></dbp-inline-notification> + <br /> + <dbp-inline-notification + summary="Item deleted" + body="Item <b>foo</b> was deleted!" + type="success"></dbp-inline-notification> + <br /> + <dbp-inline-notification + summary="Item deleted" + body="Item <b>foo</b> was deleted!" + type="danger"></dbp-inline-notification> + <br /> + <dbp-inline-notification + summary="Item deleted" + body="Item <b>foo</b> was deleted!" + type="warning"></dbp-inline-notification> </div> </div> <div class="content"> @@ -212,10 +285,12 @@ html { <div class="control" id="dbp-translated-demo"> <dbp-translated subscribe="lang"> <div slot="de"> - Dieser Text ist Deutsch und wird Englisch werden wenn man die Sprache auf Englisch stellt. + Dieser Text ist Deutsch und wird Englisch werden wenn man die + Sprache auf Englisch stellt. </div> <div slot="en"> - This text is English and will be German if the language is changed to German. + This text is English and will be German if the language is changed + to German. </div> </dbp-translated> </div> diff --git a/packages/common/dbp-lit-element.js b/packages/common/dbp-lit-element.js index b218b0925efc5f57b1d8828de9035e211b27f98e..60f77faf0339788c98fd10937830910d7527bfb8 100644 --- a/packages/common/dbp-lit-element.js +++ b/packages/common/dbp-lit-element.js @@ -1,4 +1,4 @@ -import {AdapterLitElement} from "./src/adapter-lit-element"; +import {AdapterLitElement} from './src/adapter-lit-element'; export default class DBPLitElement extends AdapterLitElement { constructor() { @@ -13,9 +13,8 @@ export default class DBPLitElement extends AdapterLitElement { static get properties() { return { ...super.properties, - htmlOverrides: { type: String, attribute: 'html-overrides' }, + htmlOverrides: {type: String, attribute: 'html-overrides'}, }; - } disconnectedCallback() { @@ -27,7 +26,9 @@ export default class DBPLitElement extends AdapterLitElement { } _(selector) { - return this.shadowRoot === null ? this.querySelector(selector) : this.shadowRoot.querySelector(selector); + return this.shadowRoot === null + ? this.querySelector(selector) + : this.shadowRoot.querySelector(selector); } firstUpdated() { @@ -39,7 +40,7 @@ export default class DBPLitElement extends AdapterLitElement { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "html-overrides": + case 'html-overrides': this._importTemplateSlots(); break; } @@ -51,10 +52,10 @@ export default class DBPLitElement extends AdapterLitElement { /** * Transforms all global override templates or named template slots in the light DOM to named div slots * on the first render. - * + * * Global overrides will replace all existing slotted elements with the same slot name. */ - _importTemplateSlots() { + _importTemplateSlots() { if (!this._renderDone) { return; } @@ -63,13 +64,13 @@ export default class DBPLitElement extends AdapterLitElement { } _importLocalTemplateSlots() { - if(this._localTemplateSlotsImported ) { + if (this._localTemplateSlotsImported) { return; } // Now extract slots from templates contained in the light dom let lightTemplateSlots = this.querySelectorAll(':scope > template[slot]:not([slot=""]'); - for(let templateElem of lightTemplateSlots) { + for (let templateElem of lightTemplateSlots) { // create a slot div container to put in the cloned template content const divElem = document.createElement('div'); divElem.slot = templateElem.getAttribute('slot'); @@ -84,7 +85,7 @@ export default class DBPLitElement extends AdapterLitElement { } _importGlobalTemplateSlots() { - if(this.htmlOverrides === '' || this._globalTemplateSlotsImported) { + if (this.htmlOverrides === '' || this._globalTemplateSlotsImported) { return; } @@ -93,13 +94,15 @@ export default class DBPLitElement extends AdapterLitElement { if (globalOverrideTemplateElem !== null) { // we need to clone the element so we can access the content const overrideTemplateElemClone = globalOverrideTemplateElem.content.cloneNode(true); - const templateOverrideElem = overrideTemplateElemClone.querySelector('template#' + this.tagName.toLowerCase()); + const templateOverrideElem = overrideTemplateElemClone.querySelector( + 'template#' + this.tagName.toLowerCase() + ); if (templateOverrideElem !== null) { const templateOverrideElemClone = templateOverrideElem.content.cloneNode(true); // Find all slots which are direct children (somehow :scope doesn't work here so check parentNode) let globalTemplateSlots = []; - for(let e of templateOverrideElemClone.querySelectorAll('[slot]:not([slot=""]')) { + for (let e of templateOverrideElemClone.querySelectorAll('[slot]:not([slot=""]')) { if (e.parentNode === templateOverrideElemClone) { globalTemplateSlots.push(e); } @@ -107,7 +110,7 @@ export default class DBPLitElement extends AdapterLitElement { // Global overrides will replace local ones. // Either normal slotted elements or the ones we create from templates. - for(let slotElem of globalTemplateSlots) { + for (let slotElem of globalTemplateSlots) { for (let elm of this.querySelectorAll('[slot="' + slotElem.slot + '"]')) { elm.remove(); } @@ -115,10 +118,10 @@ export default class DBPLitElement extends AdapterLitElement { // Create a dummy node and add it to the the same shadow root the templates are from // By adding it into the template we have the nice side effect that it is not visible - let container = document.createElement("div"); + let container = document.createElement('div'); globalOverrideTemplateElem.append(container); this._globalSlotsContainer = container; - for(let slotElem of globalTemplateSlots) { + for (let slotElem of globalTemplateSlots) { container.appendChild(slotElem); } diff --git a/packages/common/demo.js b/packages/common/demo.js index 7211728237f589fafc83a37d7444220d2ec02e75..6c1ae20c6946d9bba2817ac5fadf978ad0ee5b36 100644 --- a/packages/common/demo.js +++ b/packages/common/demo.js @@ -1 +1 @@ -import './dbp-common-demo.js'; \ No newline at end of file +import './dbp-common-demo.js'; diff --git a/packages/common/error.js b/packages/common/error.js index f001f1747cc53f3fba0b001746260745e9379250..33cfda32567a78105800572eacbf9a4b9bc3422a 100644 --- a/packages/common/error.js +++ b/packages/common/error.js @@ -1,5 +1,5 @@ import {send as notify} from './notification'; -import {createInstance} from "./src/i18n"; +import {createInstance} from './src/i18n'; /** * Escapes html @@ -22,10 +22,10 @@ export const escapeHTML = (string) => { * @returns {string} */ export const stripHTML = (string) => { - var div = document.createElement("div"); + var div = document.createElement('div'); div.innerHTML = string; - return div.textContent || div.innerText || ""; + return div.textContent || div.innerText || ''; }; /** @@ -41,9 +41,9 @@ export const errorMixin = { * @param icon * @param lang */ - handleXhrError(jqXHR, textStatus, errorThrown, icon = "sad", lang = "de") { + handleXhrError(jqXHR, textStatus, errorThrown, icon = 'sad', lang = 'de') { // return if user aborted the request - if (textStatus === "abort") { + if (textStatus === 'abort') { return; } @@ -51,9 +51,12 @@ export const errorMixin = { const i18n = createInstance(); i18n.changeLanguage(lang); - if (jqXHR.responseJSON !== undefined && jqXHR.responseJSON["hydra:description"] !== undefined) { + if ( + jqXHR.responseJSON !== undefined && + jqXHR.responseJSON['hydra:description'] !== undefined + ) { // response is a JSON-LD - body = jqXHR.responseJSON["hydra:description"]; + body = jqXHR.responseJSON['hydra:description']; } else if (jqXHR.responseJSON !== undefined && jqXHR.responseJSON['detail'] !== undefined) { // response is a plain JSON body = jqXHR.responseJSON['detail']; @@ -72,14 +75,14 @@ export const errorMixin = { } notify({ - "summary": i18n.t('error.summary'), - "body": escapeHTML(stripHTML(body)), - "icon": icon, - "type": "danger", + summary: i18n.t('error.summary'), + body: escapeHTML(stripHTML(body)), + icon: icon, + type: 'danger', }); if (this.sendSetPropertyEvent !== undefined) { - this.sendSetPropertyEvent('analytics-event', {'category': 'XhrError', 'action': body}); + this.sendSetPropertyEvent('analytics-event', {category: 'XhrError', action: body}); } }, @@ -91,9 +94,9 @@ export const errorMixin = { * @param icon * @param lang */ - handleFetchError: async function (error, summary = "", icon = "sad", lang = "de") { + handleFetchError: async function (error, summary = '', icon = 'sad', lang = 'de') { // return if user aborted the request - if (error.name === "AbortError") { + if (error.name === 'AbortError') { return; } @@ -102,41 +105,47 @@ export const errorMixin = { i18n.changeLanguage(lang); try { - await error.json().then((json) => { - if (json["hydra:description"] !== undefined) { - // response is a JSON-LD and possibly also contains HTML! - body = json["hydra:description"]; - } else if (json['detail'] !== undefined) { - // response is a plain JSON - body = json['detail']; - } else { - // no description available - body = error.statusText; - } - }).catch(() => { - body = error.statusText !== undefined ? error.statusText : error; - }); + await error + .json() + .then((json) => { + if (json['hydra:description'] !== undefined) { + // response is a JSON-LD and possibly also contains HTML! + body = json['hydra:description']; + } else if (json['detail'] !== undefined) { + // response is a plain JSON + body = json['detail']; + } else { + // no description available + body = error.statusText; + } + }) + .catch(() => { + body = error.statusText !== undefined ? error.statusText : error; + }); } catch (e) { // a TypeError means the connection to the server was refused most of the times - if (error.name === "TypeError") { - body = error.message !== "" ? error.message : i18n.t('error.connection-to-server-refused'); + if (error.name === 'TypeError') { + body = + error.message !== '' + ? error.message + : i18n.t('error.connection-to-server-refused'); } } notify({ - "summary": summary === "" ? i18n.t('error.summary') : summary, - "body": escapeHTML(stripHTML(body)), - "icon": icon, - "type": "danger", + summary: summary === '' ? i18n.t('error.summary') : summary, + body: escapeHTML(stripHTML(body)), + icon: icon, + type: 'danger', }); if (this.sendSetPropertyEvent !== undefined) { this.sendSetPropertyEvent('analytics-event', { - 'category': 'FetchError', - 'action': summary === "" ? body : summary + ": " + body + category: 'FetchError', + action: summary === '' ? body : summary + ': ' + body, }); } - } + }, }; /** @@ -146,6 +155,8 @@ export const errorMixin = { */ export const getStackTrace = () => { let stack = new Error().stack || ''; - stack = stack.split('\n').map(function (line) { return line.trim(); }); + stack = stack.split('\n').map(function (line) { + return line.trim(); + }); return stack.splice(stack[0] === 'Error' ? 2 : 1); }; diff --git a/packages/common/errorreport.js b/packages/common/errorreport.js index d6185786740b8f15ac9efdfdaf92e5b73cec144e..4f17f456ac068d921d43bf6870f064d89d7fe63b 100644 --- a/packages/common/errorreport.js +++ b/packages/common/errorreport.js @@ -7,72 +7,68 @@ let sentryDSN = ''; /** * Initializes error reporting. - * + * * If a sentry DSN is set we will use sentry, if not we will log to the console. - * + * * @param {object} [options] * @param {boolean} [options.debug=false] Enable debug output * @param {string} [options.release] The project release */ export function init(options) { - let defaults = { - debug: false, - }; - let actual = Object.assign({}, defaults, options); + let defaults = { + debug: false, + }; + let actual = Object.assign({}, defaults, options); - if (_isInitialized) - throw new Error("Already initialized"); + if (_isInitialized) throw new Error('Already initialized'); - let sentryOptions = {debug: actual.debug}; + let sentryOptions = {debug: actual.debug}; - if (actual.release) { - sentryOptions['release'] = actual.release; - } + if (actual.release) { + sentryOptions['release'] = actual.release; + } - if (actual.environment) { - sentryOptions['environment'] = actual.environment; - } + if (actual.environment) { + sentryOptions['environment'] = actual.environment; + } - if (!sentryDSN) { - if (options.debug) - console.log("No sentry DSN set, sentry disabled"); + if (!sentryDSN) { + if (options.debug) console.log('No sentry DSN set, sentry disabled'); - // In case we don't have a sentry config, we still use sentry, but print - // all events into the console don't send them to the server. - // XXX: Dummy DSN needed to make init() work. - sentryOptions['dsn'] = 'http://12345@dummy.dummy/42'; - sentryOptions['beforeSend'] = (event, hint) => { - console.error('ERR-REPORT:', hint.originalException || hint.syntheticException); - return null; - }; - } else { - sentryOptions['dsn'] = sentryDSN; - _canReportEvent = true; - } + // In case we don't have a sentry config, we still use sentry, but print + // all events into the console don't send them to the server. + // XXX: Dummy DSN needed to make init() work. + sentryOptions['dsn'] = 'http://12345@dummy.dummy/42'; + sentryOptions['beforeSend'] = (event, hint) => { + console.error('ERR-REPORT:', hint.originalException || hint.syntheticException); + return null; + }; + } else { + sentryOptions['dsn'] = sentryDSN; + _canReportEvent = true; + } - Sentry.init(sentryOptions); + Sentry.init(sentryOptions); - _isInitialized = true; + _isInitialized = true; } /** * Whether showReportDialog() will work. */ export function canReportEvent() { - if (!_isInitialized) - throw new Error("Not initialized"); - return _canReportEvent; + if (!_isInitialized) throw new Error('Not initialized'); + return _canReportEvent; } /** * Show a report dialog for user error feedback. - * + * * Call canReportEvent() first to see if this will do anything. */ export function showReportDialog() { - if (!canReportEvent()) - return; - Sentry.showReportDialog(); + if (!canReportEvent()) return; + Sentry.showReportDialog(); } /** @@ -81,9 +77,8 @@ export function showReportDialog() { * @param {*} exception */ export function captureException(exception) { - if (!_isInitialized) - throw new Error("Not initialized"); - Sentry.captureException(exception); + if (!_isInitialized) throw new Error('Not initialized'); + Sentry.captureException(exception); } /** @@ -93,11 +88,9 @@ export function captureException(exception) { * @param {string} [level=error] The loglevel (error, warning, info, debug) */ export function captureMessage(message, level) { - if (!_isInitialized) - throw new Error("Not initialized"); - if (!level) - level = 'error'; - if (!['error', 'warning', 'info', 'debug'].includes(level)) - throw new Error('Invalid log level'); - Sentry.captureMessage(message, level); -} \ No newline at end of file + if (!_isInitialized) throw new Error('Not initialized'); + if (!level) level = 'error'; + if (!['error', 'warning', 'info', 'debug'].includes(level)) + throw new Error('Invalid log level'); + Sentry.captureMessage(message, level); +} diff --git a/packages/common/i18next-scanner.config.js b/packages/common/i18next-scanner.config.js index 773819264a14879dcd454bb9a5317ccdeec2e9d8..3eb7d15907b2901987862b2619bbda8947c738c8 100644 --- a/packages/common/i18next-scanner.config.js +++ b/packages/common/i18next-scanner.config.js @@ -1,17 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - './*.js', - ], + input: ['src/*.js', './*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/common/i18next.js b/packages/common/i18next.js index e1b0b32bff6e731bc8ff1b445ac297acdec68a6c..2b9244b3608c23c74e0123a7b4076c3363346981 100644 --- a/packages/common/i18next.js +++ b/packages/common/i18next.js @@ -33,13 +33,13 @@ export function humanFileSize(bytes, si = false) { if (Math.abs(bytes) < thresh) { return bytes + ' B'; } - const units = ['kB','MB','GB','TB','PB','EB','ZB','YB']; + const units = ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; let u = -1; do { bytes /= thresh; ++u; - } while(Math.abs(bytes) >= thresh && u < units.length - 1); - return bytes.toFixed(1)+' '+units[u]; + } while (Math.abs(bytes) >= thresh && u < units.length - 1); + return bytes.toFixed(1) + ' ' + units[u]; } /** @@ -85,7 +85,7 @@ export function createInstance(languages, lng, fallback, namespace) { compatibilityJSON: 'v3', }; - Object.keys(languages).forEach(function(key) { + Object.keys(languages).forEach(function (key) { options['resources'][key] = {[namespace]: languages[key]}; }); @@ -115,10 +115,9 @@ export function setOverrides(i18n, element, overrides) { let namespace = i18n.options.fallbackNS; let overrideNamespace = getOverrideNamespace(namespace); let hasOverrides = false; - for(let lng of i18n.languages) { + for (let lng of i18n.languages) { i18n.removeResourceBundle(lng, overrideNamespace); - if (overrides[lng] === undefined || overrides[lng][tagName] === undefined) - continue; + if (overrides[lng] === undefined || overrides[lng][tagName] === undefined) continue; let resources = overrides[lng][tagName]; hasOverrides = true; i18n.addResourceBundle(lng, overrideNamespace, resources); diff --git a/packages/common/index.js b/packages/common/index.js index 825ec1495f1196541b96677d9c0129d270a2401c..0009a2f09e6baac0872c90addb531afd3ed31203 100644 --- a/packages/common/index.js +++ b/packages/common/index.js @@ -5,7 +5,7 @@ import {MiniSpinner} from './src/mini-spinner.js'; import {Button, LoadingButton} from './src/button.js'; import {Spinner} from './src/spinner.js'; import {InlineNotification} from './src/inline-notification.js'; -import {Translated} from "./src/translated"; +import {Translated} from './src/translated'; import {AdapterLitElement} from './src/adapter-lit-element.js'; export {EventBus, createLinkedAbortController, createTimeoutAbortSignal}; diff --git a/packages/common/jsonld.js b/packages/common/jsonld.js index f74e38cf8b1b46881bde1376ce4472775f6d59d5..0a42f6fa2b83c5556d8bba59110a01170fe08b68 100644 --- a/packages/common/jsonld.js +++ b/packages/common/jsonld.js @@ -1,6 +1,6 @@ import {send as notify} from './notification'; -import * as utils from "./utils"; -import {createInstance} from "./src/i18n"; +import * as utils from './utils'; +import {createInstance} from './src/i18n'; export default class JSONLD { constructor(baseApiUrl, entities) { @@ -9,7 +9,7 @@ export default class JSONLD { let idToEntityNameMatchList = {}; for (const entityName in entities) { - const id = entities[entityName]["@id"]; + const id = entities[entityName]['@id']; idToEntityNameMatchList[id] = entityName; } @@ -71,7 +71,7 @@ export default class JSONLD { static _doInitialization(apiUrl) { const xhr = new XMLHttpRequest(); const i18n = JSONLD._i18n; - xhr.open("GET", apiUrl, true); + xhr.open('GET', apiUrl, true); xhr.onreadystatechange = function () { if (xhr.readyState !== 4) { @@ -84,21 +84,22 @@ export default class JSONLD { let entryPoints = {}; for (let property in json) { // for some reason the properties start with a lower case character - if (!property.startsWith("@")) entryPoints[property.toLowerCase()] = json[property]; + if (!property.startsWith('@')) + entryPoints[property.toLowerCase()] = json[property]; } // read the link header of the api response // const utils = require("./utils"); - const links = utils.parseLinkHeader(this.getResponseHeader("link")); + const links = utils.parseLinkHeader(this.getResponseHeader('link')); // get the hydra apiDocumentation url - const apiDocUrl = links["http://www.w3.org/ns/hydra/core#apiDocumentation"]; + const apiDocUrl = links['http://www.w3.org/ns/hydra/core#apiDocumentation']; if (apiDocUrl !== undefined) { // load the hydra apiDocumentation const docXhr = new XMLHttpRequest(); - docXhr.open("GET", apiDocUrl, true); - docXhr.setRequestHeader("Content-Type", "application/json"); + docXhr.open('GET', apiDocUrl, true); + docXhr.setRequestHeader('Content-Type', 'application/json'); docXhr.onreadystatechange = function () { if (docXhr.readyState !== 4) { return; @@ -107,16 +108,25 @@ export default class JSONLD { if (docXhr.status === 200) { JSONLD._gatherEntities(docXhr, apiUrl, entryPoints); } else { - JSONLD._executeFailureFunctions(apiUrl, i18n.t('jsonld.api-documentation-server', {apiUrl: apiDocUrl})); + JSONLD._executeFailureFunctions( + apiUrl, + i18n.t('jsonld.api-documentation-server', {apiUrl: apiDocUrl}) + ); } }; docXhr.send(); } else { - JSONLD._executeFailureFunctions(apiUrl, i18n.t('jsonld.error-hydra-documentation-url-not-set', {apiUrl: apiUrl})); + JSONLD._executeFailureFunctions( + apiUrl, + i18n.t('jsonld.error-hydra-documentation-url-not-set', {apiUrl: apiUrl}) + ); } } else { - JSONLD._executeFailureFunctions(apiUrl, i18n.t('jsonld.error-api-server', {apiUrl: apiUrl})); + JSONLD._executeFailureFunctions( + apiUrl, + i18n.t('jsonld.error-api-server', {apiUrl: apiUrl}) + ); } }; @@ -132,7 +142,7 @@ export default class JSONLD { */ static _gatherEntities(docXhr, apiUrl, entryPoints) { const json = JSON.parse(docXhr.responseText); - const supportedClasses = json["hydra:supportedClass"]; + const supportedClasses = json['hydra:supportedClass']; let entities = {}; const baseUrl = utils.parseBaseUrl(apiUrl); @@ -140,10 +150,11 @@ export default class JSONLD { // gather the entities supportedClasses.forEach(function (classData) { // add entry point url - const entityName = classData["hydra:title"]; + const entityName = classData['hydra:title']; let entryPoint = entryPoints[entityName.toLowerCase()]; - if (entryPoint !== undefined && !entryPoint.startsWith("http")) entryPoint = baseUrl + entryPoint; - classData["@entryPoint"] = entryPoint; + if (entryPoint !== undefined && !entryPoint.startsWith('http')) + entryPoint = baseUrl + entryPoint; + classData['@entryPoint'] = entryPoint; entities[entityName] = classData; }); @@ -168,7 +179,7 @@ export default class JSONLD { * @param apiUrl * @param message */ - static _executeFailureFunctions(apiUrl, message = "") { + static _executeFailureFunctions(apiUrl, message = '') { const i18n = JSONLD._i18n; if (JSONLD.failureFunctions[apiUrl] !== undefined) { for (const fnc of JSONLD.failureFunctions[apiUrl]) { @@ -179,11 +190,11 @@ export default class JSONLD { } JSONLD.failureFunctions[apiUrl] = []; - if (message !== "") { + if (message !== '') { notify({ - "summary": i18n.t('error.summary'), - "body": message, - "type": "danger", + summary: i18n.t('error.summary'), + body: message, + type: 'danger', }); } } @@ -200,21 +211,21 @@ export default class JSONLD { getApiUrlForIdentifier(identifier) { const entity = this.getEntityForIdentifier(identifier); - if (entity === undefined || entity["@entryPoint"] === undefined) { + if (entity === undefined || entity['@entryPoint'] === undefined) { throw new Error(`Entity with identifier "${identifier}" not found!`); } - return entity["@entryPoint"]; + return entity['@entryPoint']; } getApiUrlForEntityName(entityName) { const entity = this.getEntityForEntityName(entityName); - if (entity === undefined || entity["@entryPoint"] === undefined) { + if (entity === undefined || entity['@entryPoint'] === undefined) { throw new Error(`Entity "${entityName}" not found!`); } - return entity["@entryPoint"]; + return entity['@entryPoint']; } getEntityNameForIdentifier(identifier) { @@ -238,14 +249,13 @@ export default class JSONLD { */ expandMember(member, context) { if (context === undefined) { - context = member["@context"]; + context = member['@context']; } - let result = {"@id": member["@id"]}; + let result = {'@id': member['@id']}; for (const key of Object.keys(context)) { const value = context[key]; - if (member[key] !== undefined) - result[value] = member[key]; + if (member[key] !== undefined) result[value] = member[key]; } return result; diff --git a/packages/common/misc/browser-check.js b/packages/common/misc/browser-check.js index 9b645a96e951cc2016861dbeef7b4038885c4822..1527c587b18b3eb6dd6046281c04699dd0343b7d 100644 --- a/packages/common/misc/browser-check.js +++ b/packages/common/misc/browser-check.js @@ -9,127 +9,129 @@ Example usage: <noscript>Diese Applikation benötigt Javascript / This application requires Javascript</noscript> */ - (function () { + // https://caniuse.com/#feat=es6 + function supportsES6() { + if (typeof Symbol == 'undefined') return false; + + try { + eval('class Foo {}'); + eval('var bar = (x) => x+1'); + } catch (e) { + console.log(e); + return false; + } -// https://caniuse.com/#feat=es6 -function supportsES6() { - if (typeof Symbol == "undefined") - return false; - - try { - eval("class Foo {}"); - eval("var bar = (x) => x+1"); - } catch (e) { - console.log(e); - return false; + return true; } - return true; -} - -// https://caniuse.com/#feat=es6-module-dynamic-import -function supportsDynamicImport() { - try { - new Function('import("")'); - return true; - } catch (err) { - return false; + // https://caniuse.com/#feat=es6-module-dynamic-import + function supportsDynamicImport() { + try { + new Function('import("")'); + return true; + } catch (err) { + return false; + } } -} - -// https://caniuse.com/#feat=shadowdomv1 -function supportsShadowDOM() { - return (typeof Element != "undefined" && 'attachShadow' in Element.prototype && 'getRootNode' in Element.prototype); -} - -// https://caniuse.com/#feat=custom-elementsv1 -function supportsCustomElements() { - return !!window.customElements; -} - -// https://caniuse.com/#feat=async-functions -function supportsAsyncAwait() { - try { - eval('async () => {}'); - } catch (e) { - return false; + + // https://caniuse.com/#feat=shadowdomv1 + function supportsShadowDOM() { + return ( + typeof Element != 'undefined' && + 'attachShadow' in Element.prototype && + 'getRootNode' in Element.prototype + ); } - return true; -} - -// https://caniuse.com/#feat=mdn-javascript_statements_import_meta -function supportsImportMeta() { - // TODO: sadly no idea how to test this.. - return true; -} - -// Eval can be disabled through https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -function supportsEval() { - try { - eval(''); - } catch (e) { - return false; + + // https://caniuse.com/#feat=custom-elementsv1 + function supportsCustomElements() { + return !!window.customElements; } - return true; -} - -// https://caniuse.com/abortcontroller -function supportsAbortController() { - // AbortController in older Safari is broken, so check for the signal property - // as well. - return (!!window.AbortController && Request.prototype.hasOwnProperty('signal')); -} - -function isBrowserSupported() { - if (!supportsEval()) { - console.log("Eval support disabled, skipping browser feature detection."); + + // https://caniuse.com/#feat=async-functions + function supportsAsyncAwait() { + try { + eval('async () => {}'); + } catch (e) { + return false; + } return true; } - if (!supportsES6()) { - console.log("ES6 not supported"); - return false; + // https://caniuse.com/#feat=mdn-javascript_statements_import_meta + function supportsImportMeta() { + // TODO: sadly no idea how to test this.. + return true; } - if (!supportsDynamicImport()) { - console.log("Dynamic imports not supported"); - return false; + // Eval can be disabled through https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + function supportsEval() { + try { + eval(''); + } catch (e) { + return false; + } + return true; } - if (!supportsShadowDOM()) { - console.log("Shadow DOM not supported"); - return false; + // https://caniuse.com/abortcontroller + function supportsAbortController() { + // AbortController in older Safari is broken, so check for the signal property + // as well. + return !!window.AbortController && Request.prototype.hasOwnProperty('signal'); } - if (!supportsCustomElements()) { - console.log("Custom Elements not supported"); - return false; - } + function isBrowserSupported() { + if (!supportsEval()) { + console.log('Eval support disabled, skipping browser feature detection.'); + return true; + } - if (!supportsAsyncAwait()) { - console.log("Async Await not supported"); - return false; - } - - if (!supportsImportMeta()) { - console.log("import.meta not supported"); - return false; - } + if (!supportsES6()) { + console.log('ES6 not supported'); + return false; + } - if (!supportsAbortController()) { - console.log("AbortController not supported"); - return false; - } + if (!supportsDynamicImport()) { + console.log('Dynamic imports not supported'); + return false; + } + + if (!supportsShadowDOM()) { + console.log('Shadow DOM not supported'); + return false; + } + + if (!supportsCustomElements()) { + console.log('Custom Elements not supported'); + return false; + } + + if (!supportsAsyncAwait()) { + console.log('Async Await not supported'); + return false; + } - return true; -} + if (!supportsImportMeta()) { + console.log('import.meta not supported'); + return false; + } -var MultiString = function(f) { - return f.toString().split('\n').slice(1, -1).join('\n'); -}; + if (!supportsAbortController()) { + console.log('AbortController not supported'); + return false; + } -var ms = MultiString(function() {/** + return true; + } + + var MultiString = function (f) { + return f.toString().split('\n').slice(1, -1).join('\n'); + }; + + var ms = MultiString(function () { + /** <style> #unsupported .overlay { font-family: sans-serif; @@ -178,14 +180,14 @@ var ms = MultiString(function() {/** </div> </div> </div> -**/}); +**/ + }); -function main() { - if (!isBrowserSupported()) { - document.body.innerHTML = ms; + function main() { + if (!isBrowserSupported()) { + document.body.innerHTML = ms; + } } -} - -main(); + main(); })(); diff --git a/packages/common/notification.js b/packages/common/notification.js index cf09ec18c8e92505955d2125b6233bfa405338cc..6c8bfc940fa2f04a265a14c1d84c515e14252eaa 100644 --- a/packages/common/notification.js +++ b/packages/common/notification.js @@ -15,7 +15,7 @@ * @param options */ function send(options) { - const event = new CustomEvent("dbp-notification-send", { + const event = new CustomEvent('dbp-notification-send', { bubbles: true, cancelable: true, detail: options, @@ -25,9 +25,13 @@ function send(options) { // true means the event was not handled if (result) { - alert((options.summary !== undefined && options.summary !== "" ? options.summary + ": " : "") + options.body); - console.log("Use the web component dbp-notification to show fancy notifications."); + alert( + (options.summary !== undefined && options.summary !== '' + ? options.summary + ': ' + : '') + options.body + ); + console.log('Use the web component dbp-notification to show fancy notifications.'); } } -export { send }; +export {send}; diff --git a/packages/common/package.json b/packages/common/package.json index 28a276f0440efe0b549374c08543e95fea9b427b..0e7c243cf905329400576603c428a4fe2e488d27 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,45 +1,49 @@ { - "name": "@dbp-toolkit/common", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/common", - "version": "0.2.13", - "module": "index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/common" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1" - }, - "scripts": { - "i18next": "i18next-scanner", - "clean": "rm dist/*", - "build": "rollup -c", - "build-test": "rollup -c --environment BUILD:test", - "test": "npm run build-test && karma start --singleRun", - "watch": "rollup -c --watch", - "lint": "eslint ." - }, - "dependencies": { - "@open-wc/scoped-elements": "^2.0.0", - "@sentry/browser": "^6.0.0", - "i18next": "^21.4.2", - "lit": "^2.0.0" - } + "name": "@dbp-toolkit/common", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/common", + "version": "0.2.13", + "module": "index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/common" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1" + }, + "scripts": { + "i18next": "i18next-scanner", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "clean": "rm dist/*", + "build": "rollup -c", + "build-test": "rollup -c --environment BUILD:test", + "test": "npm run build-test && karma start --singleRun", + "watch": "rollup -c --watch", + "lint": "eslint ." + }, + "dependencies": { + "@open-wc/scoped-elements": "^2.0.0", + "@sentry/browser": "^6.0.0", + "i18next": "^21.4.2", + "lit": "^2.0.0" + } } diff --git a/packages/common/rollup.config.js b/packages/common/rollup.config.js index e9861e3a551afff5f248f4ed4cb236db638e0b95..b9976b8376f5bea7570d2f4f25a7600d768f5871 100644 --- a/packages/common/rollup.config.js +++ b/packages/common/rollup.config.js @@ -8,22 +8,22 @@ import json from '@rollup/plugin-json'; import {getDistPath} from '../../rollup.utils.js'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build !='test') ? ['demo.js', 'components.js'] : glob.sync('test/**/*.js'), + input: build != 'test' ? ['demo.js', 'components.js'] : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), @@ -31,10 +31,15 @@ export default (async () => { copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: 'assets/icons/*.svg', dest: 'dist/' + await getDistPath(pkg.name, 'icons')}, + { + src: 'assets/icons/*.svg', + dest: 'dist/' + (await getDistPath(pkg.name, 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/common/src/abort.js b/packages/common/src/abort.js index 33d5992812a478d05fd6d849f9ccbc51c73003a1..5fecac8845544d3bea9805fda12485065478da9b 100644 --- a/packages/common/src/abort.js +++ b/packages/common/src/abort.js @@ -31,7 +31,9 @@ export function createLinkedAbortController(...signals) { export function createTimeoutAbortSignal(delay) { const controller = new AbortController(); - setTimeout(() => {controller.abort(); }, delay); + setTimeout(() => { + controller.abort(); + }, delay); return controller.signal; -} \ No newline at end of file +} diff --git a/packages/common/src/adapter-lit-element.js b/packages/common/src/adapter-lit-element.js index 023deced7877dc5e86129e689860f12d105f4a3f..726c4fcc8b8402d1d0b458a2b0887ded2a9da9b6 100644 --- a/packages/common/src/adapter-lit-element.js +++ b/packages/common/src/adapter-lit-element.js @@ -1,5 +1,5 @@ -import {LitElement} from "lit"; -import {Logger} from "./logger"; +import {LitElement} from 'lit'; +import {Logger} from './logger'; export class AdapterLitElement extends LitElement { constructor() { @@ -66,14 +66,14 @@ export class AdapterLitElement extends LitElement { if (this.deferUnSubscribe) { const attrs = this.unsubscribe.split(','); - attrs.forEach(element => this.unSubscribeProviderFor(element)); + attrs.forEach((element) => this.unSubscribeProviderFor(element)); this.deferSubscribe = false; this.unsubscribe = ''; } if (this.deferSubscribe) { const attrs = this.subscribe.split(','); - attrs.forEach(element => this.subscribeProviderFor(element)); + attrs.forEach((element) => this.subscribeProviderFor(element)); this.deferSubscribe = false; } @@ -81,69 +81,115 @@ export class AdapterLitElement extends LitElement { const that = this; - this.addEventListener('dbp-subscribe', function (e) { - const name = e.detail.name; - if (that.hasProperty(name) || that.providerRoot) { - Logger.debug('AdapterLitElementProvider(' + that.tagName + ') eventListener("dbp-subscribe",..) name "' + name + '" found.'); - that.callbackStore.push({name: name, callback: e.detail.callback, sender: e.detail.sender}); - - e.detail.callback(that.getProperty(name)); - e.stopPropagation(); - } - }, false); - - this.addEventListener('dbp-unsubscribe', function (e) { - const name = e.detail.name; - const sender = e.detail.sender; - if (that.hasProperty(name) || that.providerRoot) { - Logger.debug('AdapterLitElementProvider(' + that.tagName + ') eventListener("dbp-unsubscribe",..) name "' + name + '" found.'); - that.callbackStore.forEach(item => { - if (item.sender === sender && item.name === name) { - const index = that.callbackStore.indexOf(item); - that.callbackStore.splice(index, 1); - Logger.debug('AdapterLitElementProvider(' + that.tagName + ') eventListener for name "' + name + '" removed.'); - } - }); + this.addEventListener( + 'dbp-subscribe', + function (e) { + const name = e.detail.name; + if (that.hasProperty(name) || that.providerRoot) { + Logger.debug( + 'AdapterLitElementProvider(' + + that.tagName + + ') eventListener("dbp-subscribe",..) name "' + + name + + '" found.' + ); + that.callbackStore.push({ + name: name, + callback: e.detail.callback, + sender: e.detail.sender, + }); + + e.detail.callback(that.getProperty(name)); + e.stopPropagation(); + } + }, + false + ); + + this.addEventListener( + 'dbp-unsubscribe', + function (e) { + const name = e.detail.name; + const sender = e.detail.sender; + if (that.hasProperty(name) || that.providerRoot) { + Logger.debug( + 'AdapterLitElementProvider(' + + that.tagName + + ') eventListener("dbp-unsubscribe",..) name "' + + name + + '" found.' + ); + that.callbackStore.forEach((item) => { + if (item.sender === sender && item.name === name) { + const index = that.callbackStore.indexOf(item); + that.callbackStore.splice(index, 1); + Logger.debug( + 'AdapterLitElementProvider(' + + that.tagName + + ') eventListener for name "' + + name + + '" removed.' + ); + } + }); - e.stopPropagation(); - } - }, false); + e.stopPropagation(); + } + }, + false + ); // listen to property changes - this.addEventListener('dbp-set-property', function (e) { - const name = e.detail.name; - const value = e.detail.value; - - if (that.hasProperty(name) || that.providerRoot) { - Logger.debug('AdapterLitElementProvider(' + that.tagName + ') eventListener("dbp-set-property",..) name "' + name + '" found.'); - that.setProperty(name, value); - - that.callbackStore.forEach(item => { - if (item.name === name) { - item.callback(value); - } - }); + this.addEventListener( + 'dbp-set-property', + function (e) { + const name = e.detail.name; + const value = e.detail.value; + + if (that.hasProperty(name) || that.providerRoot) { + Logger.debug( + 'AdapterLitElementProvider(' + + that.tagName + + ') eventListener("dbp-set-property",..) name "' + + name + + '" found.' + ); + that.setProperty(name, value); + + that.callbackStore.forEach((item) => { + if (item.name === name) { + item.callback(value); + } + }); - e.stopPropagation(); - } - }, false); + e.stopPropagation(); + } + }, + false + ); // Options for the observer (which mutations to observe) - const config = { attributes: true, childList: false, subtree: false }; + const config = {attributes: true, childList: false, subtree: false}; // Callback function to execute when mutations are observed - const callback = function(mutationsList, observer) { + const callback = function (mutationsList, observer) { // Use traditional 'for loops' for IE 11 - for(const mutation of mutationsList) { + for (const mutation of mutationsList) { if (mutation.type === 'attributes') { const name = mutation.attributeName; const value = that.getAttribute(name); if (that.hasPropertyChanged(name, value)) { - Logger.debug('AdapterLitElementProvider (' + that.tagName + ') observed attribute "' + name + '" changed'); + Logger.debug( + 'AdapterLitElementProvider (' + + that.tagName + + ') observed attribute "' + + name + + '" changed' + ); that.setProperty(name, value); - that.callbackStore.forEach(item => { + that.callbackStore.forEach((item) => { if (item.name === name) { item.callback(value); } @@ -162,94 +208,123 @@ export class AdapterLitElement extends LitElement { // get all *not observed* attributes if (this.hasAttributes()) { const attrs = this.attributes; - for(let i = attrs.length - 1; i >= 0; i--) { + for (let i = attrs.length - 1; i >= 0; i--) { if (['id', 'class', 'style', 'data-tag-name'].includes(attrs[i].name)) { continue; } this.setProperty(attrs[i].name, attrs[i].value); - Logger.debug('AdapterLitElementProvider (' + that.tagName + ') found attribute "' + attrs[i].name + '" = "' + attrs[i].value + '"'); + Logger.debug( + 'AdapterLitElementProvider (' + + that.tagName + + ') found attribute "' + + attrs[i].name + + '" = "' + + attrs[i].value + + '"' + ); } } } disconnectedCallback() { const attrs = this.subscribe.split(','); - attrs.forEach(element => this.unSubscribeProviderFor(element)); + attrs.forEach((element) => this.unSubscribeProviderFor(element)); super.disconnectedCallback(); } subscribeProviderFor(element) { - Logger.debug('AdapterLitElement(' + this.tagName + ') subscribeProviderFor( ' + element + ' )'); + Logger.debug( + 'AdapterLitElement(' + this.tagName + ') subscribeProviderFor( ' + element + ' )' + ); const pair = element.trim().split(':'); const local = pair[0]; const global = pair[1] || local; const that = this; - const event = new CustomEvent('dbp-subscribe', - { - bubbles: true, - composed: true, - detail: { - name: global, - callback: (value) => { - // Don't send back "undefined" if the attribute wasn't found (for example if the providerRoot - // is used and the attribute was subscribed but not set anywhere), because that will be - // interpreted as "true" for Boolean lit-element attributes! - if (value === undefined) { - return; - } + const event = new CustomEvent('dbp-subscribe', { + bubbles: true, + composed: true, + detail: { + name: global, + callback: (value) => { + // Don't send back "undefined" if the attribute wasn't found (for example if the providerRoot + // is used and the attribute was subscribed but not set anywhere), because that will be + // interpreted as "true" for Boolean lit-element attributes! + if (value === undefined) { + return; + } - Logger.debug('AdapterLitElement(' + that.tagName + ') sub/Callback ' + global + ' -> ' + local + ' = ' + value); - - // If value is an object set it directly as property - if (typeof value === 'object' && value !== null) { - // Logger.debug("value is object", value); - that.setPropertyByAttributeName(local, value); - } else { - // Logger.debug("local, that.getPropertyByAttributeName(local), value", local, that.getPropertyByAttributeName(local), value); - that.attributeChangedCallback(local, that.getPropertyByAttributeName(local), value); - - // check if an attribute also exists in the tag - if (that.getAttribute(local) !== null) { - // we don't support attributes and provider values at the same time - console.warn('Provider callback: "' + local + '" is also an attribute in tag "' + that.tagName + '", this is not supported!'); - - // update attribute if reflectAttribute is enabled - if (that.reflectAttribute) { - that.setAttribute(local, value); - } + Logger.debug( + 'AdapterLitElement(' + + that.tagName + + ') sub/Callback ' + + global + + ' -> ' + + local + + ' = ' + + value + ); + + // If value is an object set it directly as property + if (typeof value === 'object' && value !== null) { + // Logger.debug("value is object", value); + that.setPropertyByAttributeName(local, value); + } else { + // Logger.debug("local, that.getPropertyByAttributeName(local), value", local, that.getPropertyByAttributeName(local), value); + that.attributeChangedCallback( + local, + that.getPropertyByAttributeName(local), + value + ); + + // check if an attribute also exists in the tag + if (that.getAttribute(local) !== null) { + // we don't support attributes and provider values at the same time + console.warn( + 'Provider callback: "' + + local + + '" is also an attribute in tag "' + + that.tagName + + '", this is not supported!' + ); + + // update attribute if reflectAttribute is enabled + if (that.reflectAttribute) { + that.setAttribute(local, value); } } - }, - sender: this, - } - }); + } + }, + sender: this, + }, + }); this.dispatchEvent(event); } unSubscribeProviderFor(element) { - Logger.debug('AdapterLitElement(' + this.tagName + ') unSubscribeProviderFor( ' + element + ' )'); + Logger.debug( + 'AdapterLitElement(' + this.tagName + ') unSubscribeProviderFor( ' + element + ' )' + ); const pair = element.trim().split(':'); const global = pair[1] || pair[0]; - const event = new CustomEvent('dbp-unsubscribe', - { - bubbles: true, - composed: true, - detail: { - name: global, - sender: this, - } - }); + const event = new CustomEvent('dbp-unsubscribe', { + bubbles: true, + composed: true, + detail: { + name: global, + sender: this, + }, + }); this.dispatchEvent(event); } static get properties() { return { ...super.properties, - subscribe: { type: String }, - unsubscribe: { type: String }, - providerRoot: { type: Boolean, attribute: 'provider-root' }, + subscribe: {type: String}, + unsubscribe: {type: String}, + providerRoot: {type: Boolean, attribute: 'provider-root'}, }; } @@ -271,14 +346,22 @@ export class AdapterLitElement extends LitElement { } attributeChangedCallback(name, oldValue, newValue) { - switch(name) { + switch (name) { case 'subscribe': - Logger.debug('AdapterLitElement() attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')'); + Logger.debug( + 'AdapterLitElement() attributeChangesCallback( ' + + name + + ', ' + + oldValue + + ', ' + + newValue + + ')' + ); if (this.subscribe && this.subscribe.length > 0) { if (this.connected) { const attrs = this.subscribe.split(','); - attrs.forEach(element => this.unSubscribeProviderFor(element)); + attrs.forEach((element) => this.unSubscribeProviderFor(element)); } else { this.deferUnSubscribe = this.subscribe.length > 0; this.unsubscribe = this.subscribe; @@ -289,7 +372,7 @@ export class AdapterLitElement extends LitElement { this.subscribe = newValue; if (this.connected) { const attrs = newValue.split(','); - attrs.forEach(element => this.subscribeProviderFor(element)); + attrs.forEach((element) => this.subscribeProviderFor(element)); } else { this.deferSubscribe = newValue && newValue.length > 0; } @@ -299,7 +382,10 @@ export class AdapterLitElement extends LitElement { // The function should not be called if oldValue is an object, oldValue and newValue are empty // or if newValue is empty but name and oldValue are set // This should prevent 'Uncaught SyntaxError: JSON.parse unexpected end of data at line 1 column 1 of the JSON data' - if ((typeof oldValue === 'object' && !oldValue && !newValue) || (!newValue && oldValue && name)) { + if ( + (typeof oldValue === 'object' && !oldValue && !newValue) || + (!newValue && oldValue && name) + ) { // Logger.debug("attributeChangedCallback ignored", name, oldValue, newValue); break; } @@ -325,7 +411,7 @@ export class AdapterLitElement extends LitElement { const event = new CustomEvent('dbp-set-property', { bubbles: true, composed: true, - detail: {'name': name, 'value': value} + detail: {name: name, value: value}, }); // dispatch the dbp-set-property event to the parent (if there is any) so that the current element diff --git a/packages/common/src/button.js b/packages/common/src/button.js index 95d08ac1403f34af239d88edbb1c7f288daf29eb..1c9a975272e4d90820b7fbe6b00e29343fbe5419 100644 --- a/packages/common/src/button.js +++ b/packages/common/src/button.js @@ -15,8 +15,8 @@ import * as commonStyles from '../styles.js'; export class Button extends ScopedElementsMixin(LitElement) { constructor() { super(); - this.value = ""; - this.type = ""; + this.value = ''; + this.type = ''; this.spinner = false; this.noSpinnerOnClick = false; this.disabled = false; @@ -34,11 +34,11 @@ export class Button extends ScopedElementsMixin(LitElement) { static get properties() { return { - value: { type: String }, - type: { type: String }, - spinner: { type: Boolean }, - noSpinnerOnClick: { type: Boolean, attribute: 'no-spinner-on-click' }, - disabled: { type: Boolean, reflect: true }, + value: {type: String}, + type: {type: String}, + spinner: {type: Boolean}, + noSpinnerOnClick: {type: Boolean, attribute: 'no-spinner-on-click'}, + disabled: {type: Boolean, reflect: true}, }; } @@ -68,14 +68,22 @@ export class Button extends ScopedElementsMixin(LitElement) { ${commonStyles.getThemeCSS()} ${commonStyles.getButtonCSS()} - .spinner { margin-left: 0.5em; } + .spinner { + margin-left: 0.5em; + } `; } render() { return html` - <button @click="${this.clickHandler}" class="button ${this.type}" ?disabled="${this.disabled}"> - ${this.value} <dbp-mini-spinner class="spinner" style="display: ${this.spinner ? "inline" : "none"}"></dbp-mini-spinner> + <button + @click="${this.clickHandler}" + class="button ${this.type}" + ?disabled="${this.disabled}"> + ${this.value} + <dbp-mini-spinner + class="spinner" + style="display: ${this.spinner ? 'inline' : 'none'}"></dbp-mini-spinner> </button> `; } @@ -84,15 +92,15 @@ export class Button extends ScopedElementsMixin(LitElement) { export class LoadingButton extends ScopedElementsMixin(LitElement) { constructor() { super(); - this.value = ""; - this.type = ""; + this.value = ''; + this.type = ''; this.loading = false; this.disabled = false; // https://bugs.chromium.org/p/chromium/issues/detail?id=1061240#c12 this.addEventListener('click', (e) => { if (this.disabled) { - e.stopImmediatePropagation(); + e.stopImmediatePropagation(); } }); } @@ -106,10 +114,10 @@ export class LoadingButton extends ScopedElementsMixin(LitElement) { static get properties() { return { // value is deprecated, use the main slot instead - value: { type: String }, - type: { type: String }, - loading: { type: Boolean }, - disabled: { type: Boolean, reflect: true }, + value: {type: String}, + type: {type: String}, + loading: {type: Boolean}, + disabled: {type: Boolean, reflect: true}, }; } @@ -158,9 +166,7 @@ export class LoadingButton extends ScopedElementsMixin(LitElement) { width: 100%; } - @media only screen - and (orientation: portrait) - and (max-width: 768px) { + @media only screen and (orientation: portrait) and (max-width: 768px) { .button { min-height: 36px; } @@ -174,8 +180,15 @@ export class LoadingButton extends ScopedElementsMixin(LitElement) { render() { return html` - <button class="button ${this.type} loading-container ${!this.loading ? "is-not-loading" : ""}" ?disabled="${this.disabled}"> - <div class="label"><slot>${this.value}</slot></div> <dbp-mini-spinner class="spinner" style="display: ${this.loading ? "inline" : "none"}"></dbp-mini-spinner> + <button + class="button ${this.type} loading-container ${!this.loading + ? 'is-not-loading' + : ''}" + ?disabled="${this.disabled}"> + <div class="label"><slot>${this.value}</slot></div> + <dbp-mini-spinner + class="spinner" + style="display: ${this.loading ? 'inline' : 'none'}"></dbp-mini-spinner> </button> `; } diff --git a/packages/common/src/eventbus.js b/packages/common/src/eventbus.js index d77662e9c523b7d68fe3f6e2b6a104c886611393..ca96b2ba45eae322a8c7bc5205bb6243b4b9dc8b 100644 --- a/packages/common/src/eventbus.js +++ b/packages/common/src/eventbus.js @@ -6,9 +6,8 @@ const OPERATION_FETCH_RETAINED = 'fetch-retained'; -export function checkIndentifier(name, allowEmpty=false) { - if (name.length === 0 && allowEmpty) - return; +export function checkIndentifier(name, allowEmpty = false) { + if (name.length === 0 && allowEmpty) return; // we are strict here, so we can used special characters to extend the format later on if (!/^[a-z]+[a-z0-9-]*$/.test(name)) { throw new Error('Only a-z0-9 and - allowed: ' + JSON.stringify(name)); @@ -30,13 +29,12 @@ export function createEventName(busName, eventName, operation) { * An event bus implementation which doesn't depend on a global bus instance and supports retained messages * (similar to MQTT retained messages) */ -export class EventBus -{ +export class EventBus { /** * @param {object} options * @param {string} options.name The bus name, events will only be visible on the same bus */ - constructor(options={}) { + constructor(options = {}) { const {name = ''} = options; this._busName = name; this._retainedData = {}; @@ -65,8 +63,7 @@ export class EventBus const eventHandler = (e) => { const meta = {}; const detail = e.detail; - if (detail.retain !== undefined) - meta.retain = detail.retain; + if (detail.retain !== undefined) meta.retain = detail.retain; callback(detail.data, meta); e.preventDefault(); }; @@ -76,7 +73,7 @@ export class EventBus this._listeners[name] = listeners.set(callback, eventHandler); const fetchEvent = new CustomEvent(this._name(name, OPERATION_FETCH_RETAINED), { - detail: {callback: eventHandler} + detail: {callback: eventHandler}, }); window.dispatchEvent(fetchEvent); } @@ -91,7 +88,7 @@ export class EventBus const listeners = this._listeners[name] || new Map(); const eventHandler = listeners.get(callback); if (eventHandler === undefined) { - throw new Error("Not subscribed to: " + name); + throw new Error('Not subscribed to: ' + name); } window.removeEventListener(this._name(name), eventHandler); listeners.delete(callback); @@ -100,13 +97,13 @@ export class EventBus /** * Publish a value for an event name. Set the retained flag to send the event also to future subscribers. * - * @param {string} name - * @param {any} data + * @param {string} name + * @param {any} data * @param {object} options * @param {boolean} options.retain If the event should be retained i.e. send to all future subscribers as well * @returns {boolean} If the event was handled by at least one bus member. */ - publish(name, data, options={}) { + publish(name, data, options = {}) { const {retain = false} = options; const eventName = this._name(name); @@ -116,11 +113,16 @@ export class EventBus if (data !== undefined) { const callback = e.detail['callback']; e.stopImmediatePropagation(); - const event = new CustomEvent(eventName, {detail: {data: data, retain: retain}}); + const event = new CustomEvent(eventName, { + detail: {data: data, retain: retain}, + }); callback(event); } }; - window.addEventListener(this._name(name, OPERATION_FETCH_RETAINED), retainedEventHandler); + window.addEventListener( + this._name(name, OPERATION_FETCH_RETAINED), + retainedEventHandler + ); const eventHandler = (e) => { const detail = e.detail; @@ -133,7 +135,10 @@ export class EventBus this._retainedListeners[name] = [retainedEventHandler, eventHandler]; } - const event = new CustomEvent(eventName, {detail: {data: data, retain: retain}, cancelable: true}); + const event = new CustomEvent(eventName, { + detail: {data: data, retain: retain}, + cancelable: true, + }); return !window.dispatchEvent(event); } diff --git a/packages/common/src/i18n.js b/packages/common/src/i18n.js index ebd734720b5a52bbd4008d0e503ca96f9d3fa068..6623ebdc2d5144e117f9df22d98a8b866ae3c1ba 100644 --- a/packages/common/src/i18n.js +++ b/packages/common/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/common/src/i18n/de/translation.json b/packages/common/src/i18n/de/translation.json index 879cba7624f22fceb5bbb933ecd06249695a792c..cedfe4733c401f948892f5a75e8897c74a14bfa8 100644 --- a/packages/common/src/i18n/de/translation.json +++ b/packages/common/src/i18n/de/translation.json @@ -1,11 +1,11 @@ { - "error": { - "summary": "Ein Fehler ist aufgetreten", - "connection-to-server-refused": "Verbindungs zum Server verweigert!" - }, - "jsonld": { - "error-api-server": "Verbindung zum API Server {{apiUrl}} fehlgeschlagen!", - "error-hydra-documentation-url-not-set": "Hydra apiDocumentation URL wurden für server {{apiUrl}} nicht gesetzt!", - "api-documentation-server": "Verbindung zum apiDocumentation API Server {{apiDocUrl}} fehlgeschlagen!" - } + "error": { + "summary": "Ein Fehler ist aufgetreten", + "connection-to-server-refused": "Verbindungs zum Server verweigert!" + }, + "jsonld": { + "error-api-server": "Verbindung zum API Server {{apiUrl}} fehlgeschlagen!", + "error-hydra-documentation-url-not-set": "Hydra apiDocumentation URL wurden für server {{apiUrl}} nicht gesetzt!", + "api-documentation-server": "Verbindung zum apiDocumentation API Server {{apiDocUrl}} fehlgeschlagen!" + } } diff --git a/packages/common/src/i18n/en/translation.json b/packages/common/src/i18n/en/translation.json index e9cbcac4405a9b51666b85a5c474aba1eefec9c2..4e3cd1dfcfa312d0a5c7a0f977922a2d75dbc80e 100644 --- a/packages/common/src/i18n/en/translation.json +++ b/packages/common/src/i18n/en/translation.json @@ -1,11 +1,11 @@ { - "error": { - "summary": "An error occurred", - "connection-to-server-refused": "Connection to server refused!" - }, - "jsonld": { - "error-api-server": "Connection to api server {{apiUrl}} failed!", - "error-hydra-documentation-url-not-set": "Hydra apiDocumentation url was not set for server {{apiUrl}}!", - "api-documentation-server": "Connection to apiDocumentation server {{apiDocUrl}} failed!" - } + "error": { + "summary": "An error occurred", + "connection-to-server-refused": "Connection to server refused!" + }, + "jsonld": { + "error-api-server": "Connection to api server {{apiUrl}} failed!", + "error-hydra-documentation-url-not-set": "Hydra apiDocumentation url was not set for server {{apiUrl}}!", + "api-documentation-server": "Connection to apiDocumentation server {{apiDocUrl}} failed!" + } } diff --git a/packages/common/src/icon.js b/packages/common/src/icon.js index 98d94c08c9edc76fb0d8aa456d7a4190c311bba8..6e318cd825f09c75a172cee0a6957c024dc611e2 100644 --- a/packages/common/src/icon.js +++ b/packages/common/src/icon.js @@ -10,8 +10,8 @@ export function getIconCSS(name) { const iconURL = getIconSVGURL(name); return ` background-color: currentColor; - mask-image: url(${ iconURL }); - -webkit-mask-image: url(${ iconURL }); + mask-image: url(${iconURL}); + -webkit-mask-image: url(${iconURL}); mask-size: contain; -webkit-mask-size: contain; mask-repeat: no-repeat; @@ -28,17 +28,16 @@ export function getIconCSS(name) { * For icon names see https://lineicons.com */ export class Icon extends LitElement { - constructor() { super(); - this.name = "bolt"; + this.name = 'bolt'; } static get properties() { - return { - name: { type: String }, + return { + name: {type: String}, }; - } + } static get styles() { // language=css @@ -47,7 +46,7 @@ export class Icon extends LitElement { display: inline-block; height: 1em; width: 1em; - top: .125em; + top: 0.125em; position: relative; } @@ -63,7 +62,7 @@ export class Icon extends LitElement { -webkit-mask-position: center; } `; - } + } render() { const iconURL = getIconSVGURL(this.name); @@ -79,4 +78,4 @@ export class Icon extends LitElement { <div id="svg"></div> `; } -} \ No newline at end of file +} diff --git a/packages/common/src/inline-notification.js b/packages/common/src/inline-notification.js index fa11ba4663db3ff073420d7899201f5c0974b591..bb27ac111c14cc02f921a2a38eb4f209a98981d9 100644 --- a/packages/common/src/inline-notification.js +++ b/packages/common/src/inline-notification.js @@ -4,13 +4,13 @@ import * as commonStyles from '../styles'; /** * Inline Notification - * + * * Summary can be a string or empty - * + * * Body can be a string, html or empty - * + * * Type can be primary/info/success/warning/danger (default: info) - * + * */ export class InlineNotification extends DBPLitElement { constructor() { @@ -22,9 +22,9 @@ export class InlineNotification extends DBPLitElement { static get properties() { return { - type: { type: String }, - summary: { type: String }, - body: { type: String }, + type: {type: String}, + summary: {type: String}, + body: {type: String}, }; } @@ -51,13 +51,15 @@ export class InlineNotification extends DBPLitElement { .notification h3 { margin: 0 0 3px 0; font: inherit; - font-weight: bold; + font-weight: bold; } `; } createBodyHtml() { - return document.createRange().createContextualFragment(`<slot name="body">${ this.body }</slot>`); + return document + .createRange() + .createContextualFragment(`<slot name="body">${this.body}</slot>`); } render() { @@ -66,12 +68,18 @@ export class InlineNotification extends DBPLitElement { return html` <div class="columns"> <div class="column"> - <div id="inline-notification" class="notification is-${ this.type !== '' ? this.type : 'info' }"> - ${ this.summary !== '' ? html`<h3>${ this.summary }</h3>` : `` } - ${ bodyHtml } + <div + id="inline-notification" + class="notification is-${this.type !== '' ? this.type : 'info'}"> + ${this.summary !== '' + ? html` + <h3>${this.summary}</h3> + ` + : ``} + ${bodyHtml} </div> </div> </div> `; } -} \ No newline at end of file +} diff --git a/packages/common/src/logger.js b/packages/common/src/logger.js index 97d5cf5fad371b9a3c3ad00c80ba9a91fc9a750f..c13c9909c97f7d6dcef7bdf9eda06d7090d1a87e 100644 --- a/packages/common/src/logger.js +++ b/packages/common/src/logger.js @@ -1,6 +1,6 @@ class LoggerType { get debug() { - if (window.location.hash.includes("debug")) { + if (window.location.hash.includes('debug')) { return console.debug; } else { return () => {}; @@ -8,4 +8,4 @@ class LoggerType { } } -export const Logger = new LoggerType(); \ No newline at end of file +export const Logger = new LoggerType(); diff --git a/packages/common/src/mini-spinner.js b/packages/common/src/mini-spinner.js index 5dfe9db8832a9f4de38c8f07f459b7729399815c..027c0f5d0b4e3bbcf289e0bec0e1812eb5c89b0c 100644 --- a/packages/common/src/mini-spinner.js +++ b/packages/common/src/mini-spinner.js @@ -3,69 +3,87 @@ import {html, LitElement, css} from 'lit'; export class MiniSpinner extends LitElement { constructor() { super(); - this.text = ""; + this.text = ''; } static get properties() { return { - text: { type: String }, + text: {type: String}, }; } static get styles() { // language=css return css` - .outer { - display: inline-block; - vertical-align: sub; - } - .inner { - display: flex; - } - .ring { - display: inline-block; - position: relative; - width: 1em; - height: 1em; - } - .ring div { - box-sizing: border-box; - display: block; - position: absolute; - width: 100%; - height: 100%; - border: 0.2em solid currentColor; - border-radius: 50%; - animation: ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - border-color: currentColor transparent transparent transparent; - } - .ring div:nth-child(1) { - animation-delay: -0.45s; - } - .ring div:nth-child(2) { - animation-delay: -0.3s; - } - .ring div:nth-child(3) { - animation-delay: -0.15s; - } - @keyframes ring { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } - } - .text { - display: inline-block; - margin-left: 0.5em; - font-size: 0.7em; - }`; - } + .outer { + display: inline-block; + vertical-align: sub; + } + .inner { + display: flex; + } + .ring { + display: inline-block; + position: relative; + width: 1em; + height: 1em; + } + .ring div { + box-sizing: border-box; + display: block; + position: absolute; + width: 100%; + height: 100%; + border: 0.2em solid currentColor; + border-radius: 50%; + animation: ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; + border-color: currentColor transparent transparent transparent; + } + .ring div:nth-child(1) { + animation-delay: -0.45s; + } + .ring div:nth-child(2) { + animation-delay: -0.3s; + } + .ring div:nth-child(3) { + animation-delay: -0.15s; + } + @keyframes ring { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + .text { + display: inline-block; + margin-left: 0.5em; + font-size: 0.7em; + } + `; + } render() { - const textHtml = this.text !== "" ? html`<div class="text">${this.text}</div>` : html``; + const textHtml = + this.text !== '' + ? html` + <div class="text">${this.text}</div> + ` + : html``; - return html`<div class="outer"><div class="inner"><div class="ring"><div></div><div></div><div></div><div></div></div>${textHtml}</div></div>`; + return html` + <div class="outer"> + <div class="inner"> + <div class="ring"> + <div></div> + <div></div> + <div></div> + <div></div> + </div> + ${textHtml} + </div> + </div> + `; } } diff --git a/packages/common/src/spinner.js b/packages/common/src/spinner.js index cf2569bd5f8e4b7e31bcb6457bb2107c6fe119c0..6e4e1a4e3c7059a139460345d033391db4cf5fca 100644 --- a/packages/common/src/spinner.js +++ b/packages/common/src/spinner.js @@ -2,7 +2,6 @@ // other web components (assuming it's not bundled) export class Spinner extends HTMLElement { - constructor() { super(); let shadowRoot = this.attachShadow({mode: 'open'}); @@ -115,4 +114,4 @@ transform:translateX(-100%) translateY(0%); visibility:visible; <div id="all-spinner-tuglogo-box-5" class="all-spinner-tuglogo-box"></div> </div>`; } -} \ No newline at end of file +} diff --git a/packages/common/src/translated.js b/packages/common/src/translated.js index 592f4925a858c32a8d55e6ff58ec77e783802bdb..ff11258ab502887917c524574a5971ab36802acc 100644 --- a/packages/common/src/translated.js +++ b/packages/common/src/translated.js @@ -1,6 +1,6 @@ import {css, html} from 'lit'; import {classMap} from 'lit/directives/class-map.js'; -import DBPLitElement from "../dbp-lit-element"; +import DBPLitElement from '../dbp-lit-element'; export class Translated extends DBPLitElement { constructor() { @@ -11,14 +11,16 @@ export class Translated extends DBPLitElement { static get properties() { return { ...super.properties, - lang: { type: String }, + lang: {type: String}, }; - } + } static get styles() { // language=css return css` - .hidden {display: none} + .hidden { + display: none; + } `; } diff --git a/packages/common/src/utils.js b/packages/common/src/utils.js index a3db6d6a4d9ebfc7561a919cfaeadff72efdac3b..a2a2deb3fb70cb4eace08403baeddc1f74430ac5 100644 --- a/packages/common/src/utils.js +++ b/packages/common/src/utils.js @@ -2,7 +2,7 @@ * Appends the second relative or absolute URL by treating * the base URL as the root path. Unlike normal URL join which * treats the host as root path. - * + * * http://example.com/foo + bar -> http://example.com/foo/bar * http://example.com/foo/ + /bar -> http://example.com/foo/bar * @@ -10,8 +10,8 @@ * @param {string} addedURL The URL to append ot the baseURL */ export const combineURLs = (baseURL, addedURL) => { - if(!baseURL.endsWith('/')) { + if (!baseURL.endsWith('/')) { baseURL += '/'; } return new URL(addedURL.replace(/^\/+/, ''), baseURL).href; -}; \ No newline at end of file +}; diff --git a/packages/common/styles.js b/packages/common/styles.js index f846a3e350cc8f95770dd70aa5ea0a736e9cbce9..4cc45328cdc4a351fc655a1081d15b43aca30d64 100644 --- a/packages/common/styles.js +++ b/packages/common/styles.js @@ -9,111 +9,236 @@ import {getIconSVGURL} from './src/icon.js'; export function getThemeCSS() { // language=css return css` - - :host { - /* old variables */ - --dbp-primary-bg-color: var(--dbp-override-primary-bg-color, #007bff); - --dbp-primary-text-color: var(--dbp-override-primary-text-color, #fff); - --dbp-primary-button-border: var(--dbp-override-primary-button-border, #007bff); - --dbp-secondary-bg-color: var(--dbp-override-secondary-bg-color, #6c757d); - --dbp-secondary-text-color: var(--dbp-override-secondary-text-color, #fff); - --dbp-info-bg-color: var(--dbp-override-info-bg-color, #17a2b8); - --dbp-info-text-color: var(--dbp-override-info-text-color, #fff); - --dbp-success-bg-color: var(--dbp-override-success-bg-color, #28a745); - --dbp-success-text-color: var(--dbp-override-success-text-color, #fff); - --dbp-warning-bg-color: var(--dbp-override-warning-bg-color, #ffc107); - --dbp-warning-text-color: var(--dbp-override-warning-text-color, #343a40); - --dbp-warning-color: var(--dbp-override-warning-color, #D57A1C); - --dbp-danger-bg-color: var(--dbp-override-danger-bg-color, #dc3545); - --dbp-danger-text-color: var(--dbp-override-danger-text-color, #fff); - --dbp-light: var(--dbp-override-light, #f8f9fa); - --dbp-dark: var(--dbp-override-dark, #343a40); - --dbp-muted-text: var(--dbp-override-muted-text, #6c757d); - --dbp-border-width: var(--dbp-override-border-width, 1px); - --dbp-border-color: var(--dbp-override-border-color, #000); - --dbp-placeholder-color: #777; - --dbp-downloaded-bg-color: var(--dbp-override-downloaded-bg-color, #c8dcc8); - - - /* old new variables remove in future */ - --dbp-base-light: var(--dbp-override-base-light, var(--dbp-override-light, #ffffff)); - --dbp-base-dark: var(--dbp-override-base-dark, var(--dbp-override-dark, #000000)); - --dbp-text-light: var(--dbp-override-text-light, var(--dbp-override-light, #ffffff)); - --dbp-text-dark: var(--dbp-override-text-dark, var(--dbp-override-dark, #000000)); - --dbp-text-muted-light: var(--dbp-override-text-muted-light, var(--dbp-override-muted-text, #adadad)); - --dbp-text-muted-dark: var(--dbp-override-text-muted-dark, var(--dbp-override-muted-text, #767676)); - --dbp-accent-light: var(--dbp-override-accent-light, var(--dbp-override-primary-bg-color, #c24f68)); - --dbp-accent-dark: var(--dbp-override-accent-dark, var(--dbp-override-primary-bg-color, #c24f68)); - --dbp-primary-light: var(--dbp-override-primary-light, var(--dbp-override-primary-bg-color, #8ca4eb)); /*remove second value if no app needs to be backported */ - --dbp-primary-dark: var(--dbp-override-primary-dark, var(--dbp-override-primary-bg-color, #2a4491)); - --dbp-secondary-light: var(--dbp-override-secondary-light, var(--dbp-override-light, #ffffff)); - --dbp-secondary-dark: var(--dbp-override-secondary-dark, var(--dbp-override-dark, #000000)); - --dbp-info-light: var(--dbp-override-info-light, var(--dbp-override-primary-bg-color, #8ca4eb)); - --dbp-info-dark: var(--dbp-override-info-dark, var(--dbp-override-primary-bg-color, #2a4491)); - --dbp-success-light: var(--dbp-override-success-light, var(--dbp-override-success-bg-color, #7acc79)); - --dbp-success-dark: var(--dbp-override-success-dark, var(--dbp-override-success-bg-color, #188018)); - --dbp-warning-light: var(--dbp-override-warning-color, var(--dbp-override-warning-light, #f99a41)); - --dbp-warning-dark: var(--dbp-override-warning-color, var(--dbp-override-warning-dark, #c15500)); - --dbp-danger-light: var(--dbp-override-danger-bg-color, var(--dbp-override-danger-light, #ff887a)); - --dbp-danger-dark: var(--dbp-override-danger-bg-color, var(--dbp-override-danger-dark, #de3535)); - --dbp-border-light: var(--dbp-override-border-light, 1px solid #ffffff); - --dbp-border-dark: var(--dbp-override-border-dark, 1px solid #000000); - /*--dbp-border-radius: var(--dbp-override-border-radius, 0px); + :host { + /* old variables */ + --dbp-primary-bg-color: var(--dbp-override-primary-bg-color, #007bff); + --dbp-primary-text-color: var(--dbp-override-primary-text-color, #fff); + --dbp-primary-button-border: var(--dbp-override-primary-button-border, #007bff); + --dbp-secondary-bg-color: var(--dbp-override-secondary-bg-color, #6c757d); + --dbp-secondary-text-color: var(--dbp-override-secondary-text-color, #fff); + --dbp-info-bg-color: var(--dbp-override-info-bg-color, #17a2b8); + --dbp-info-text-color: var(--dbp-override-info-text-color, #fff); + --dbp-success-bg-color: var(--dbp-override-success-bg-color, #28a745); + --dbp-success-text-color: var(--dbp-override-success-text-color, #fff); + --dbp-warning-bg-color: var(--dbp-override-warning-bg-color, #ffc107); + --dbp-warning-text-color: var(--dbp-override-warning-text-color, #343a40); + --dbp-warning-color: var(--dbp-override-warning-color, #d57a1c); + --dbp-danger-bg-color: var(--dbp-override-danger-bg-color, #dc3545); + --dbp-danger-text-color: var(--dbp-override-danger-text-color, #fff); + --dbp-light: var(--dbp-override-light, #f8f9fa); + --dbp-dark: var(--dbp-override-dark, #343a40); + --dbp-muted-text: var(--dbp-override-muted-text, #6c757d); + --dbp-border-width: var(--dbp-override-border-width, 1px); + --dbp-border-color: var(--dbp-override-border-color, #000); + --dbp-placeholder-color: #777; + --dbp-downloaded-bg-color: var(--dbp-override-downloaded-bg-color, #c8dcc8); + + /* old new variables remove in future */ + --dbp-base-light: var(--dbp-override-base-light, var(--dbp-override-light, #ffffff)); + --dbp-base-dark: var(--dbp-override-base-dark, var(--dbp-override-dark, #000000)); + --dbp-text-light: var(--dbp-override-text-light, var(--dbp-override-light, #ffffff)); + --dbp-text-dark: var(--dbp-override-text-dark, var(--dbp-override-dark, #000000)); + --dbp-text-muted-light: var( + --dbp-override-text-muted-light, + var(--dbp-override-muted-text, #adadad) + ); + --dbp-text-muted-dark: var( + --dbp-override-text-muted-dark, + var(--dbp-override-muted-text, #767676) + ); + --dbp-accent-light: var( + --dbp-override-accent-light, + var(--dbp-override-primary-bg-color, #c24f68) + ); + --dbp-accent-dark: var( + --dbp-override-accent-dark, + var(--dbp-override-primary-bg-color, #c24f68) + ); + --dbp-primary-light: var( + --dbp-override-primary-light, + var(--dbp-override-primary-bg-color, #8ca4eb) + ); /*remove second value if no app needs to be backported */ + --dbp-primary-dark: var( + --dbp-override-primary-dark, + var(--dbp-override-primary-bg-color, #2a4491) + ); + --dbp-secondary-light: var( + --dbp-override-secondary-light, + var(--dbp-override-light, #ffffff) + ); + --dbp-secondary-dark: var( + --dbp-override-secondary-dark, + var(--dbp-override-dark, #000000) + ); + --dbp-info-light: var( + --dbp-override-info-light, + var(--dbp-override-primary-bg-color, #8ca4eb) + ); + --dbp-info-dark: var( + --dbp-override-info-dark, + var(--dbp-override-primary-bg-color, #2a4491) + ); + --dbp-success-light: var( + --dbp-override-success-light, + var(--dbp-override-success-bg-color, #7acc79) + ); + --dbp-success-dark: var( + --dbp-override-success-dark, + var(--dbp-override-success-bg-color, #188018) + ); + --dbp-warning-light: var( + --dbp-override-warning-color, + var(--dbp-override-warning-light, #f99a41) + ); + --dbp-warning-dark: var( + --dbp-override-warning-color, + var(--dbp-override-warning-dark, #c15500) + ); + --dbp-danger-light: var( + --dbp-override-danger-bg-color, + var(--dbp-override-danger-light, #ff887a) + ); + --dbp-danger-dark: var( + --dbp-override-danger-bg-color, + var(--dbp-override-danger-dark, #de3535) + ); + --dbp-border-light: var(--dbp-override-border-light, 1px solid #ffffff); + --dbp-border-dark: var(--dbp-override-border-dark, 1px solid #000000); + /*--dbp-border-radius: var(--dbp-override-border-radius, 0px); --dbp-hover-base: var(--dbp-override-hover-base, var(--dbp-override-dark)); --dbp-hover-text: var(--dbp-override-hover-text, var(--dbp-override-light));*/ - - /* new new variables */ - --dbp-base: var(--dbp-override-base, var(--dbp-override-base-light, var(--dbp-override-light, #ffffff))); - --dbp-base-inverted: var(--dbp-override-base-inverted, var(--dbp-override-base, var(--dbp-override-base-light, var(--dbp-override-light, #000000)))); - --dbp-text: var(--dbp-override-text, var(--dbp-override-text-dark, var(--dbp-override-dark, #000000))); - --dbp-text-inverted: var(--dbp-override-text-inverted, var(--dbp-override-text-light, var(--dbp-override-light, #ffffff))); - --dbp-text-muted: var(--dbp-override-text-muted, var(--dbp-override-text-muted-dark, var(--dbp-override-muted-text, #767676))); - --dbp-accent: var(--dbp-override-accent, var(--dbp-override-accent-dark, var(--dbp-override-primary-bg-color, #c24f68))); - --dbp-primary-base: var(--dbp-override-primary-base, var(--dbp-override-primary-dark, var(--dbp-override-primary-bg-color, #2a4491))); - --dbp-primary-text: var(--dbp-override-primary-text, var(--dbp-override-text-light, var(--dbp-override-light, #ffffff))); - --dbp-primary-border: var(--dbp-override-primary-border, var(--dbp-override-border, var(--dbp-override-border-dark, 1px solid #000000))); - --dbp-secondary-base: var(--dbp-override-secondary-base, var(--dbp-override-secondary-light, var(--dbp-override-light, #ffffff))); - --dbp-secondary-text: var(--dbp-override-secondary-text, var(--dbp-override-secondary-dark, var(--dbp-override-dark, #000000))); - --dbp-secondary-border: var(--dbp-override-secondary-border, var(--dbp-override-border, var(--dbp-override-border-dark, 1px solid #000000))); - --dbp-info: var(--dbp-override-info, var(--dbp-override-info-dark, var(--dbp-override-primary-bg-color, #2a4491))); - --dbp-success: var(--dbp-override-success, var(--dbp-override-success-dark, var(--dbp-override-success-bg-color, #188018))); - --dbp-warning-as-text: var(--dbp-override-warning-as-text, var(--dbp-override-warning-color, var(--dbp-override-warning-dark, #c15500))); - --dbp-warning-text: var(--dbp-override-warning-text, #000000); - --dbp-warning: var(--dbp-override-warning, var(--dbp-override-warning-color, var(--dbp-override-warning-light, #ffad4d))); - --dbp-danger: var(--dbp-override-danger, var(--dbp-override-danger-bg-color, var(--dbp-override-danger-dark, #de3535))); - --dbp-border: var(--dbp-override-border, var(--dbp-override-border-dark, 1px solid #000000)); - --dbp-border-radius: var(--dbp-override-border-radius, 0px); - --dbp-hover-base: var(--dbp-override-hover-base, var(--dbp-override-dark)); - --dbp-hover-text: var(--dbp-override-hover-text, var(--dbp-override-light)); - } - - #root{ - background-color: var(--dbp-base); - color: var(--dbp-text); - } - - ::-moz-selection { - color: var(--dbp-primary-text); - background: var(--dbp-primary-base); - } - - ::selection { - color: var(--dbp-primary-text); - background: var(--dbp-primary-base); - } - - + + /* new new variables */ + --dbp-base: var( + --dbp-override-base, + var(--dbp-override-base-light, var(--dbp-override-light, #ffffff)) + ); + --dbp-base-inverted: var( + --dbp-override-base-inverted, + var( + --dbp-override-base, + var(--dbp-override-base-light, var(--dbp-override-light, #000000)) + ) + ); + --dbp-text: var( + --dbp-override-text, + var(--dbp-override-text-dark, var(--dbp-override-dark, #000000)) + ); + --dbp-text-inverted: var( + --dbp-override-text-inverted, + var(--dbp-override-text-light, var(--dbp-override-light, #ffffff)) + ); + --dbp-text-muted: var( + --dbp-override-text-muted, + var(--dbp-override-text-muted-dark, var(--dbp-override-muted-text, #767676)) + ); + --dbp-accent: var( + --dbp-override-accent, + var(--dbp-override-accent-dark, var(--dbp-override-primary-bg-color, #c24f68)) + ); + --dbp-primary-base: var( + --dbp-override-primary-base, + var(--dbp-override-primary-dark, var(--dbp-override-primary-bg-color, #2a4491)) + ); + --dbp-primary-text: var( + --dbp-override-primary-text, + var(--dbp-override-text-light, var(--dbp-override-light, #ffffff)) + ); + --dbp-primary-border: var( + --dbp-override-primary-border, + var(--dbp-override-border, var(--dbp-override-border-dark, 1px solid #000000)) + ); + --dbp-secondary-base: var( + --dbp-override-secondary-base, + var(--dbp-override-secondary-light, var(--dbp-override-light, #ffffff)) + ); + --dbp-secondary-text: var( + --dbp-override-secondary-text, + var(--dbp-override-secondary-dark, var(--dbp-override-dark, #000000)) + ); + --dbp-secondary-border: var( + --dbp-override-secondary-border, + var(--dbp-override-border, var(--dbp-override-border-dark, 1px solid #000000)) + ); + --dbp-info: var( + --dbp-override-info, + var(--dbp-override-info-dark, var(--dbp-override-primary-bg-color, #2a4491)) + ); + --dbp-success: var( + --dbp-override-success, + var(--dbp-override-success-dark, var(--dbp-override-success-bg-color, #188018)) + ); + --dbp-warning-as-text: var( + --dbp-override-warning-as-text, + var(--dbp-override-warning-color, var(--dbp-override-warning-dark, #c15500)) + ); + --dbp-warning-text: var(--dbp-override-warning-text, #000000); + --dbp-warning: var( + --dbp-override-warning, + var(--dbp-override-warning-color, var(--dbp-override-warning-light, #ffad4d)) + ); + --dbp-danger: var( + --dbp-override-danger, + var(--dbp-override-danger-bg-color, var(--dbp-override-danger-dark, #de3535)) + ); + --dbp-border: var( + --dbp-override-border, + var(--dbp-override-border-dark, 1px solid #000000) + ); + --dbp-border-radius: var(--dbp-override-border-radius, 0px); + --dbp-hover-base: var(--dbp-override-hover-base, var(--dbp-override-dark)); + --dbp-hover-text: var(--dbp-override-hover-text, var(--dbp-override-light)); + } + + #root { + background-color: var(--dbp-base); + color: var(--dbp-text); + } + + ::-moz-selection { + color: var(--dbp-primary-text); + background: var(--dbp-primary-base); + } + + ::selection { + color: var(--dbp-primary-text); + background: var(--dbp-primary-base); + } `; } export function getGeneralCSS(doMarginPaddingReset = true) { // language=css - const marginPaddingResetCss = doMarginPaddingReset ? css` - blockquote, body, dd, dl, dt, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, html, iframe, legend, li, ol, p, pre, textarea, ul { - margin: 0; - padding: 0; - } - ` : css``; + const marginPaddingResetCss = doMarginPaddingReset + ? css` + blockquote, + body, + dd, + dl, + dt, + fieldset, + figure, + h1, + h2, + h3, + h4, + h5, + h6, + hr, + html, + iframe, + legend, + li, + ol, + p, + pre, + textarea, + ul { + margin: 0; + padding: 0; + } + ` + : css``; // language=css return css` @@ -243,7 +368,9 @@ export function getGeneralCSS(doMarginPaddingReset = true) { select:not(.select) { -moz-appearance: none;.dropdown-menu -webkit-appearance: none; - background: calc(100% - 0.2rem) center no-repeat url("${unsafeCSS(getIconSVGURL('chevron-down'))}"); + background: calc(100% - 0.2rem) center no-repeat url("${unsafeCSS( + getIconSVGURL('chevron-down') + )}"); background-size: 25%; border: var(--dbp-border); border-radius: var(--dbp-border-radius); @@ -281,15 +408,24 @@ export function getFormAddonsCSS() { margin-right: 0; } - .buttons.has-addons .button:hover, .buttons.has-addons .button.is-hovered { + .buttons.has-addons .button:hover, + .buttons.has-addons .button.is-hovered { z-index: 2; } - .buttons.has-addons .button:focus, .buttons.has-addons .button.is-focused, .buttons.has-addons .button:active, .buttons.has-addons .button.is-active, .buttons.has-addons .button.is-selected { + .buttons.has-addons .button:focus, + .buttons.has-addons .button.is-focused, + .buttons.has-addons .button:active, + .buttons.has-addons .button.is-active, + .buttons.has-addons .button.is-selected { z-index: 3; } - .buttons.has-addons .button:focus:hover, .buttons.has-addons .button.is-focused:hover, .buttons.has-addons .button:active:hover, .buttons.has-addons .button.is-active:hover, .buttons.has-addons .button.is-selected:hover { + .buttons.has-addons .button:focus:hover, + .buttons.has-addons .button.is-focused:hover, + .buttons.has-addons .button:active:hover, + .buttons.has-addons .button.is-active:hover, + .buttons.has-addons .button.is-selected:hover { z-index: 4; } @@ -360,7 +496,8 @@ export function getFormAddonsCSS() { border-top-left-radius: 0; } - .field.has-addons .control .button:not([disabled]):hover, .field.has-addons .control .button:not([disabled]).is-hovered, + .field.has-addons .control .button:not([disabled]):hover, + .field.has-addons .control .button:not([disabled]).is-hovered, .field.has-addons .control .input:not([disabled]):hover, .field.has-addons .control .input:not([disabled]).is-hovered, .field.has-addons .control .select select:not([disabled]):hover, @@ -368,7 +505,10 @@ export function getFormAddonsCSS() { z-index: 2; } - .field.has-addons .control .button:not([disabled]):focus, .field.has-addons .control .button:not([disabled]).is-focused, .field.has-addons .control .button:not([disabled]):active, .field.has-addons .control .button:not([disabled]).is-active, + .field.has-addons .control .button:not([disabled]):focus, + .field.has-addons .control .button:not([disabled]).is-focused, + .field.has-addons .control .button:not([disabled]):active, + .field.has-addons .control .button:not([disabled]).is-active, .field.has-addons .control .input:not([disabled]):focus, .field.has-addons .control .input:not([disabled]).is-focused, .field.has-addons .control .input:not([disabled]):active, @@ -380,7 +520,10 @@ export function getFormAddonsCSS() { z-index: 3; } - .field.has-addons .control .button:not([disabled]):focus:hover, .field.has-addons .control .button:not([disabled]).is-focused:hover, .field.has-addons .control .button:not([disabled]):active:hover, .field.has-addons .control .button:not([disabled]).is-active:hover, + .field.has-addons .control .button:not([disabled]):focus:hover, + .field.has-addons .control .button:not([disabled]).is-focused:hover, + .field.has-addons .control .button:not([disabled]):active:hover, + .field.has-addons .control .button:not([disabled]).is-active:hover, .field.has-addons .control .input:not([disabled]):focus:hover, .field.has-addons .control .input:not([disabled]).is-focused:hover, .field.has-addons .control .input:not([disabled]):active:hover, @@ -487,10 +630,11 @@ export function getNotificationCSS() { } export function getButtonCSS() { - // language=css return css` - button.button, .button, button.dt-button { + button.button, + .button, + button.dt-button { border: var(--dbp-border); border-radius: var(--dbp-border-radius); color: var(--dbp-text); @@ -511,79 +655,95 @@ export function getButtonCSS() { border: var(--dbp-secondary-border); } - button.button:hover:enabled, .button:hover:enabled, button.dt-button:hover:enabled, button.dt-button:hover:not(.disabled) { + button.button:hover:enabled, + .button:hover:enabled, + button.dt-button:hover:enabled, + button.dt-button:hover:not(.disabled) { color: var(--dbp-hover-text, var(--dbp-secondary-text)); background-color: var(--dbp-hover-base, var(--dbp-secondary-base)); border-color: var(--dbp-hover-base, var(--dbp-secondary-base)); } - button.button.is-small, .button.is-small { + button.button.is-small, + .button.is-small { border-radius: calc(var(--dbp-border-radius) / 2); - font-size: .75rem; + font-size: 0.75rem; } - button.button.is-primary, .button.is-primary { + button.button.is-primary, + .button.is-primary { background-color: var(--dbp-primary-base); border: var(--dbp-primary-border); color: var(--dbp-primary-text); } - button.button.is-primary:hover:enabled, .button.is-primary:hover:enabled { + button.button.is-primary:hover:enabled, + .button.is-primary:hover:enabled { background-color: var(--dbp-hover-base, var(--dbp-primary-base)); color: var(--dbp-hover-text, var(--dbp-primary-text)); } - button.button.is-info, .button.is-info { + button.button.is-info, + .button.is-info { background-color: var(--dbp-info); border: var(--dbp-border); color: var(--dbp-text-inverted); } - button.button.is-info:hover:enabled, .button.is-info:hover:enabled { + button.button.is-info:hover:enabled, + .button.is-info:hover:enabled { background-color: var(--dbp-hover-base, var(--dbp-info)); color: var(--dbp-hover-text, var(--dbp-text-inverted)); } - button.button.is-success, .button.is-success { + button.button.is-success, + .button.is-success { background-color: var(--dbp-success); border: var(--dbp-border); color: var(--dbp-text-inverted); } - button.button.is-success:hover:enabled, .button.is-success:hover:enabled { + button.button.is-success:hover:enabled, + .button.is-success:hover:enabled { background-color: var(--dbp-hover-base, var(--dbp-success)); color: var(--dbp-hover-text, var(--dbp-text-inverted)); } - button.button.is-warning, .button.is-warning { + button.button.is-warning, + .button.is-warning { background-color: var(--dbp-warning); border: var(--dbp-border); color: var(--dbp-text); } - button.button.is-warning:hover:enabled, .button.is-warning:hover:enabled { + button.button.is-warning:hover:enabled, + .button.is-warning:hover:enabled { background-color: var(--dbp-hover-base, var(--dbp-warning)); color: var(--dbp-hover-text, var(--dbp-text)); } - .button.button.is-danger, .button.is-danger { + .button.button.is-danger, + .button.is-danger { background-color: var(--dbp-danger); border: var(--dbp-border); color: var(--dbp-text-inverted); } - .button.button.is-danger:hover:enabled, .button.is-danger:hover:enabled { + .button.button.is-danger:hover:enabled, + .button.is-danger:hover:enabled { background-color: var(--dbp-hover-base, var(--dbp-danger)); color: var(--dbp-hover-text, var(--dbp-text-inverted)); } - button.button[disabled], .button[disabled], fieldset[disabled] .button { - opacity: .4; + button.button[disabled], + .button[disabled], + fieldset[disabled] .button { + opacity: 0.4; cursor: not-allowed; } - button:focus-visible{ - outline:none !important; + button:focus-visible { + outline: none !important; outline-width: 0 !important; box-shadow: none; -moz-box-shadow: none; @@ -595,8 +755,7 @@ export function getButtonCSS() { export function getRadioAndCheckboxCss() { // language=css - return css` - + return css` /* Radiobutton: <label class="button-container"> @@ -612,7 +771,7 @@ export function getRadioAndCheckboxCss() { <span class="checkmark"></span> </label> */ - + .button-container { display: block; position: relative; @@ -623,8 +782,9 @@ export function getRadioAndCheckboxCss() { -ms-user-select: none; user-select: none; } - - .button-container input[type="radio"], .button-container input[type="checkbox"] { + + .button-container input[type='radio'], + .button-container input[type='checkbox'] { position: absolute; opacity: 0; cursor: pointer; @@ -632,7 +792,7 @@ export function getRadioAndCheckboxCss() { width: 0; left: 0px; } - + .checkmark { position: absolute; top: 0; @@ -643,7 +803,7 @@ export function getRadioAndCheckboxCss() { border-radius: 0px; border: var(--dbp-border); } - + .radiobutton { position: absolute; top: 0; @@ -654,34 +814,34 @@ export function getRadioAndCheckboxCss() { border: solid; border-radius: 100%; border: var(--dbp-border); - + box-sizing: content-box; } - .button-container input[type="radio"]:checked ~ .radiobutton:after { + .button-container input[type='radio']:checked ~ .radiobutton:after { border-color: var(--dbp-base); } - - .button-container input[type="radio"]:disabled ~ .radiobutton { + + .button-container input[type='radio']:disabled ~ .radiobutton { border-color: var(--dbp-text-muted); background-color: var(--dbp-text-muted); } - .button-container input[type="radio"]:checked:disabled ~ .radiobutton:after { + .button-container input[type='radio']:checked:disabled ~ .radiobutton:after { border-color: var(--dbp-text-muted); background-color: var(--dbp-text-muted); } - + .radiobutton:after { - content: ""; + content: ''; position: absolute; display: none; } - - .button-container input[type="radio"]:checked ~ .radiobutton:after { + + .button-container input[type='radio']:checked ~ .radiobutton:after { display: block; } - + .button-container .radiobutton:after { left: 0px; top: 0px; @@ -693,42 +853,41 @@ export function getRadioAndCheckboxCss() { border: 2px solid var(--dbp-base); box-sizing: border-box; } - - .button-container input[type="checkbox"]:checked ~ .checkmark:after { + + .button-container input[type='checkbox']:checked ~ .checkmark:after { border-bottom: var(--dbp-border); border-right: var(--dbp-border); border-width: 0 2px 2px 0; } - .button-container input[type="checkbox"]:focus-visible ~ .checkmark{ - outline:none !important; + .button-container input[type='checkbox']:focus-visible ~ .checkmark { + outline: none !important; outline-width: 0 !important; box-shadow: none; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: 0px 0px 4px 2px var(--dbp-accent); } - - - .button-container input[type="checkbox"]:disabled ~ .checkmark { + + .button-container input[type='checkbox']:disabled ~ .checkmark { border-color: var(--dbp-text-muted); background-color: var(--dbp-text-muted); } - .button-container input[type="checkbox"]:checked:disabled ~ .checkmark:after { + .button-container input[type='checkbox']:checked:disabled ~ .checkmark:after { border-color: var(--dbp-text-muted); } .checkmark:after { - content: ""; + content: ''; position: absolute; display: none; } - - .button-container input[type="checkbox"]:checked ~ .checkmark:after { + + .button-container input[type='checkbox']:checked ~ .checkmark:after { display: block; } - + .button-container .checkmark:after { left: 7px; top: 4px; @@ -740,7 +899,6 @@ export function getRadioAndCheckboxCss() { -ms-transform: rotate(45deg); transform: rotate(45deg); } - `; } @@ -878,9 +1036,10 @@ export function getTagCSS() { width: 2em; } - .tag:not(body).is-delete::before, .tag:not(body).is-delete::after { + .tag:not(body).is-delete::before, + .tag:not(body).is-delete::after { background-color: currentColor; - content: ""; + content: ''; display: block; left: 50%; position: absolute; @@ -901,7 +1060,8 @@ export function getTagCSS() { width: 1px; } - .tag:not(body).is-delete:hover, .tag:not(body).is-delete:focus { + .tag:not(body).is-delete:hover, + .tag:not(body).is-delete:focus { background-color: var(--dbp-text-inverted); } @@ -922,7 +1082,9 @@ export function getTagCSS() { export function getDocumentationCSS() { // language=css return css` - .documentation h1, .documentation h2, .documentation h3 { + .documentation h1, + .documentation h2, + .documentation h3 { margin: 1em 0 0.8em 0; } @@ -940,7 +1102,9 @@ export function getDocumentationCSS() { background-color: var(--dbp-hover-base); } - .documentation ul, .documentation ol, .documentation li { + .documentation ul, + .documentation ol, + .documentation li { margin: inherit; padding: inherit; } @@ -979,7 +1143,7 @@ export function getSelect2CSS() { .select2-container--default .select2-selection--single { height: 100% !important; } - .select2-container--default .select2-selection__rendered{ + .select2-container--default .select2-selection__rendered { word-wrap: break-word !important; text-overflow: inherit !important; white-space: normal !important; @@ -1007,7 +1171,7 @@ export function getModalDialogCSS() { } .modal-overlay::before { - content: ""; + content: ''; width: 100%; height: 100%; position: absolute; @@ -1030,7 +1194,7 @@ export function getModalDialogCSS() { position: relative; border-radius: var(--dbp-border-radius); } - + .modal-close { background: transparent; border: none; @@ -1039,8 +1203,9 @@ export function getModalDialogCSS() { cursor: pointer; padding: 0px; } - - .modal-close .close-icon svg, .close-icon{ + + .modal-close .close-icon svg, + .close-icon { pointer-events: none; } @@ -1048,7 +1213,6 @@ export function getModalDialogCSS() { outline: none; } - /**************************\\ Modal Animation Style \\**************************/ @@ -1096,43 +1260,39 @@ export function getModalDialogCSS() { display: block; } - .micromodal-slide[aria-hidden="false"] .modal-overlay { - animation: mmfadeIn .3s cubic-bezier(0.0, 0.0, 0.2, 1); + .micromodal-slide[aria-hidden='false'] .modal-overlay { + animation: mmfadeIn 0.3s cubic-bezier(0, 0, 0.2, 1); } - .micromodal-slide[aria-hidden="false"] .modal-container { - animation: mmslideIn .3s cubic-bezier(0, 0, .2, 1); + .micromodal-slide[aria-hidden='false'] .modal-container { + animation: mmslideIn 0.3s cubic-bezier(0, 0, 0.2, 1); } - .micromodal-slide[aria-hidden="true"] .modal-overlay { - animation: mmfadeOut .3s cubic-bezier(0.0, 0.0, 0.2, 1); + .micromodal-slide[aria-hidden='true'] .modal-overlay { + animation: mmfadeOut 0.3s cubic-bezier(0, 0, 0.2, 1); } - .micromodal-slide[aria-hidden="true"] .modal-container { - animation: mmslideOut .3s cubic-bezier(0, 0, .2, 1); + .micromodal-slide[aria-hidden='true'] .modal-container { + animation: mmslideOut 0.3s cubic-bezier(0, 0, 0.2, 1); } .micromodal-slide .modal-container, .micromodal-slide .modal-overlay { will-change: transform; } - - @media only screen - and (orientation: landscape) - and (max-width: 768px) { - .modal-container { - width: 100%; - height: 100%; - max-width: 100%; - } - - .micromodal-slide .modal-container{ + + @media only screen and (orientation: landscape) and (max-width: 768px) { + .modal-container { + width: 100%; + height: 100%; + max-width: 100%; + } + + .micromodal-slide .modal-container { height: 100%; width: 100%; } } - - `; } @@ -1173,8 +1333,7 @@ export function getActivityCSS() { margin-bottom: 0px; } - - .subheadline{ + .subheadline { font-style: italic; padding-left: 2em; margin-top: -1px; @@ -1187,18 +1346,26 @@ export function getActivityCSS() { export function getLinkCss() { // language=css return css` - .int-link-external, .int-link-internal, .link, .link-without-hover { + .int-link-external, + .int-link-internal, + .link, + .link-without-hover { border-bottom: 1px solid var(--dbp-text); } - .int-link-external:hover, .int-link-internal:hover, .link:hover { + .int-link-external:hover, + .int-link-internal:hover, + .link:hover { color: var(--dbp-hover-text, var(--dbp-text)); border-color: var(--dbp-hover-text, var(--dbp-text)); background-color: var(--dbp-hover-base); } - .int-link-external:after, .int-link-internal:after, .link:after, .link-without-hover:after { - content: "\\00a0\\00a0\\00a0"; + .int-link-external:after, + .int-link-internal:after, + .link:after, + .link-without-hover:after { + content: '\\00a0\\00a0\\00a0'; background-color: var(--dbp-text); -webkit-mask-image: url('data:image/svg+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Ebene_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2022.7%2062.4%22%20style%3D%22enable-background%3Anew%200%200%2022.7%2062.4%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cg%20transform%3D%22translate%28-382.21%20-336.98%29%22%3E%0A%09%3Cg%3E%0A%09%09%3Cpath%20d%3D%22M386.9%2C380.5c-0.2%2C0-0.4-0.1-0.6-0.3c-0.3-0.3-0.3-0.8%2C0.1-1.1l12.5-10.9l-12.5-10.9c-0.3-0.3-0.4-0.8-0.1-1.1%0A%09%09%09c0.3-0.3%2C0.8-0.4%2C1.1-0.1l13.1%2C11.5c0.2%2C0.2%2C0.3%2C0.4%2C0.3%2C0.6s-0.1%2C0.5-0.3%2C0.6l-13.1%2C11.5C387.3%2C380.4%2C387.1%2C380.5%2C386.9%2C380.5z%22%0A%09%09%09%2F%3E%0A%09%3C%2Fg%3E%0A%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A'); mask-image: url('data:image/svg+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Ebene_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2022.7%2062.4%22%20style%3D%22enable-background%3Anew%200%200%2022.7%2062.4%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cg%20transform%3D%22translate%28-382.21%20-336.98%29%22%3E%0A%09%3Cg%3E%0A%09%09%3Cpath%20d%3D%22M386.9%2C380.5c-0.2%2C0-0.4-0.1-0.6-0.3c-0.3-0.3-0.3-0.8%2C0.1-1.1l12.5-10.9l-12.5-10.9c-0.3-0.3-0.4-0.8-0.1-1.1%0A%09%09%09c0.3-0.3%2C0.8-0.4%2C1.1-0.1l13.1%2C11.5c0.2%2C0.2%2C0.3%2C0.4%2C0.3%2C0.6s-0.1%2C0.5-0.3%2C0.6l-13.1%2C11.5C387.3%2C380.4%2C387.1%2C380.5%2C386.9%2C380.5z%22%0A%09%09%09%2F%3E%0A%09%3C%2Fg%3E%0A%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A'); @@ -1212,9 +1379,10 @@ export function getLinkCss() { mask-size: 120%; } - .int-link-external:hover::after, .int-link-internal:hover::after, .link:hover::after{ + .int-link-external:hover::after, + .int-link-internal:hover::after, + .link:hover::after { background-color: var(--dbp-hover-text, var(--dbp-text)); } `; } - diff --git a/packages/common/test/abort.js b/packages/common/test/abort.js index f1dccbc55607b9f45416045759ca8e994c322d43..862ca2967838e53d76c609cffd0de9a141ddade2 100644 --- a/packages/common/test/abort.js +++ b/packages/common/test/abort.js @@ -17,4 +17,4 @@ suite('abort', () => { const signal = createTimeoutAbortSignal(10000000); assert.isFalse(signal.aborted); }); -}); \ No newline at end of file +}); diff --git a/packages/common/test/eventbus.js b/packages/common/test/eventbus.js index dc49ae571fdd6933f07eef6be76e3c87caf8b31a..0255f8f3d973a03a72f5f120c329e62bdd34154b 100644 --- a/packages/common/test/eventbus.js +++ b/packages/common/test/eventbus.js @@ -14,11 +14,11 @@ suite('helpers', () => { checkIndentifier('', true); - for(let key of ok) { + for (let key of ok) { checkIndentifier(key); } - for(let key of notOk) { + for (let key of notOk) { assert.throws(() => { checkIndentifier(key); }); @@ -35,12 +35,12 @@ suite('events', () => { test('pub sub', () => { const bus = new EventBus(); let called = false; - bus.subscribe("foo", (data) => { + bus.subscribe('foo', (data) => { called = true; assert.deepEqual(data, 42); }); - const res = bus.publish("foo", 42); + const res = bus.publish('foo', 42); assert.isTrue(called); assert.isTrue(res); bus.close(); @@ -48,7 +48,7 @@ suite('events', () => { test('no handler', () => { const bus = new EventBus(); - const res = bus.publish("foo", 42); + const res = bus.publish('foo', 42); assert.isFalse(res); bus.close(); }); @@ -60,10 +60,10 @@ suite('events', () => { const func = () => { called = true; }; - bus.subscribe("foo", func); - bus.unsubscribe("foo", func); + bus.subscribe('foo', func); + bus.unsubscribe('foo', func); - const res = bus.publish("foo", 42); + const res = bus.publish('foo', 42); assert.isFalse(res); assert.isFalse(called); bus.close(); @@ -77,9 +77,9 @@ suite('events', () => { calledData = {data: data, meta: meta}; }; - bus.subscribe("foo", func); + bus.subscribe('foo', func); - let res = bus.publish("foo", 42, {retain: true}); + let res = bus.publish('foo', 42, {retain: true}); assert.isTrue(res); assert.equal(calledData.data, 42); @@ -87,15 +87,15 @@ suite('events', () => { calledData = null; - res = bus.publish("foo", 24); + res = bus.publish('foo', 24); assert.isTrue(res); assert.equal(calledData.data, 24); assert.isFalse(calledData.meta.retain); - bus.unsubscribe("foo", func); + bus.unsubscribe('foo', func); calledData = null; - bus.subscribe("foo", func); + bus.subscribe('foo', func); assert.equal(calledData.data, 42); assert.isTrue(calledData.meta.retain); @@ -111,9 +111,9 @@ suite('events', () => { const func = () => { called = true; }; - bus.subscribe("foo", func); + bus.subscribe('foo', func); - const res = bus2.publish("foo", 42); + const res = bus2.publish('foo', 42); assert.isTrue(res); assert.isTrue(called); @@ -123,10 +123,10 @@ suite('events', () => { test('multiple retain conflict', () => { const bus = new EventBus(); - bus.publish("foo", 42, {retain: true}); + bus.publish('foo', 42, {retain: true}); const bus2 = new EventBus(); - bus.publish("foo", 24, {retain: true}); + bus.publish('foo', 24, {retain: true}); const bus3 = new EventBus(); @@ -136,7 +136,7 @@ suite('events', () => { callCount++; calledData = {data: data, meta: meta}; }; - bus3.subscribe("foo", func); + bus3.subscribe('foo', func); assert.equal(callCount, 1); assert.deepEqual(calledData.data, 24); @@ -146,4 +146,4 @@ suite('events', () => { bus2.close(); bus.close(); }); -}); \ No newline at end of file +}); diff --git a/packages/common/test/i18next.js b/packages/common/test/i18next.js index dd311e5fee6798393b7474f8ab0cdb7559c52d40..cd5213ba8574ac3da345431e5f0570381f27d013 100644 --- a/packages/common/test/i18next.js +++ b/packages/common/test/i18next.js @@ -3,29 +3,33 @@ import * as i18next from '../i18next.js'; suite('i18next', () => { test('createInstance', () => { - var inst = i18next.createInstance({de: {}}, 'de', 'en'); + var inst = i18next.createInstance({de: {}}, 'de', 'en'); assert.exists(inst); assert.deepEqual(inst.languages, ['de', 'en']); }); test('translations', () => { - var inst = i18next.createInstance({de: {foo: 'bar'}, en: {foo: 'baz', extra: 'quux'}}, 'de', 'en'); + var inst = i18next.createInstance( + {de: {foo: 'bar'}, en: {foo: 'baz', extra: 'quux'}}, + 'de', + 'en' + ); assert.deepEqual(inst.languages, ['de', 'en']); - assert.equal( inst.t('foo'), 'bar'); - assert.equal( inst.t('nope'), 'nope'); - assert.equal( inst.t('extra'), 'quux'); + assert.equal(inst.t('foo'), 'bar'); + assert.equal(inst.t('nope'), 'nope'); + assert.equal(inst.t('extra'), 'quux'); inst.changeLanguage('en'); assert.deepEqual(inst.languages, ['en', 'de']); - assert.equal( inst.t('foo'), 'baz'); - assert.equal( inst.t('nope'), 'nope'); + assert.equal(inst.t('foo'), 'baz'); + assert.equal(inst.t('nope'), 'nope'); inst.changeLanguage('nope'); assert.deepEqual(inst.languages, ['nope', 'en', 'de']); - assert.equal( inst.t('foo'), 'baz'); - assert.equal( inst.t('nope'), 'nope'); + assert.equal(inst.t('foo'), 'baz'); + assert.equal(inst.t('nope'), 'nope'); }); test('date format', () => { - var inst = i18next.createInstance({de: {}}, 'de', 'en'); + var inst = i18next.createInstance({de: {}}, 'de', 'en'); assert.deepEqual(inst.languages, ['de', 'en']); var date = new Date('1995-12-17T03:24:00'); @@ -36,7 +40,7 @@ suite('i18next', () => { }); test('number format', () => { - var inst = i18next.createInstance({de: {}}, 'de', 'en'); + var inst = i18next.createInstance({de: {}}, 'de', 'en'); assert.deepEqual(inst.languages, ['de', 'en']); assert.equal(i18next.numberFormat(inst, 42), '42'); @@ -51,7 +55,7 @@ suite('i18next', () => { test('overrides', () => { let namespace = 'some-ns'; let element = document.createElement(namespace); - var inst = i18next.createInstance({en: {foo: 'bar'}}, 'en', 'en', namespace); + var inst = i18next.createInstance({en: {foo: 'bar'}}, 'en', 'en', namespace); assert.equal(inst.t('foo'), 'bar'); assert.equal(inst.t('quux'), 'quux'); i18next.setOverrides(inst, element, {en: {[namespace]: {quux: 'bla'}}}); diff --git a/packages/common/test/unit.js b/packages/common/test/unit.js index c72b634599f04ff175366f99ad82a506630a1d47..7bf4ac4d4e1926cbb8cf727e25edecafb3712543 100644 --- a/packages/common/test/unit.js +++ b/packages/common/test/unit.js @@ -19,7 +19,7 @@ suite('utils', () => { this.foo = 42; } } - var res = utils.defineCustomElement("test-some-element", SomeElement); + var res = utils.defineCustomElement('test-some-element', SomeElement); expect(res).to.equal(true); var node = document.createElement('test-some-element'); @@ -27,19 +27,21 @@ suite('utils', () => { }); test('defineCustomElement multiple times', () => { - class SomeElement2 extends HTMLElement { - } - let res = utils.defineCustomElement("test-some-element-2", SomeElement2); + class SomeElement2 extends HTMLElement {} + let res = utils.defineCustomElement('test-some-element-2', SomeElement2); assert.isTrue(res); - res = utils.defineCustomElement("test-some-element-2", SomeElement2); + res = utils.defineCustomElement('test-some-element-2', SomeElement2); assert.isTrue(res); }); test('getAssetURL', () => { // Backwards compat - assert.equal(new URL(utils.getAssetURL("foo/bar")).pathname, "/foo/bar"); + assert.equal(new URL(utils.getAssetURL('foo/bar')).pathname, '/foo/bar'); // Normal usage - assert.equal(new URL(utils.getAssetURL('foobar', 'bar/quux')).pathname, "/local/foobar/bar/quux"); + assert.equal( + new URL(utils.getAssetURL('foobar', 'bar/quux')).pathname, + '/local/foobar/bar/quux' + ); }); test('getThemeCSS', () => { @@ -47,16 +49,25 @@ suite('utils', () => { }); test('combineURLs', () => { - assert.equal(combineURLs('http://example.org/foo', 'bar'), "http://example.org/foo/bar"); - assert.equal(combineURLs('http://example.org/foo', '/bar'), "http://example.org/foo/bar"); - assert.equal(combineURLs('http://example.org/foo/', '/bar/'), "http://example.org/foo/bar/"); - assert.equal(combineURLs('http://example.org', '/bar'), "http://example.org/bar"); - assert.equal(combineURLs('http://example.org', 'bar/'), "http://example.org/bar/"); - assert.equal(combineURLs('http://example.org', ''), "http://example.org/"); - assert.equal(combineURLs('http://example.org/bla', ''), "http://example.org/bla/"); - assert.equal(combineURLs('http://example.org/bla/', ''), "http://example.org/bla/"); - assert.equal(combineURLs('http://example.org', 'http://other.com'), "http://other.com/"); - assert.equal(combineURLs('http://example.org', 'http://other.com/test'), "http://other.com/test"); - assert.equal(combineURLs('http://example.org', 'http://other.com/test/'), "http://other.com/test/"); + assert.equal(combineURLs('http://example.org/foo', 'bar'), 'http://example.org/foo/bar'); + assert.equal(combineURLs('http://example.org/foo', '/bar'), 'http://example.org/foo/bar'); + assert.equal( + combineURLs('http://example.org/foo/', '/bar/'), + 'http://example.org/foo/bar/' + ); + assert.equal(combineURLs('http://example.org', '/bar'), 'http://example.org/bar'); + assert.equal(combineURLs('http://example.org', 'bar/'), 'http://example.org/bar/'); + assert.equal(combineURLs('http://example.org', ''), 'http://example.org/'); + assert.equal(combineURLs('http://example.org/bla', ''), 'http://example.org/bla/'); + assert.equal(combineURLs('http://example.org/bla/', ''), 'http://example.org/bla/'); + assert.equal(combineURLs('http://example.org', 'http://other.com'), 'http://other.com/'); + assert.equal( + combineURLs('http://example.org', 'http://other.com/test'), + 'http://other.com/test' + ); + assert.equal( + combineURLs('http://example.org', 'http://other.com/test/'), + 'http://other.com/test/' + ); }); }); diff --git a/packages/common/utils.js b/packages/common/utils.js index 963628775ceb9c9bd688078a1f29bfaf4b6473bb..57939027c576fcd199f8aec970c51ee787f1cbc9 100644 --- a/packages/common/utils.js +++ b/packages/common/utils.js @@ -7,7 +7,7 @@ */ export const parseLinkHeader = (header) => { if (header.length === 0) { - throw new Error("input must not be of zero length"); + throw new Error('input must not be of zero length'); } // Split parts by comma @@ -15,7 +15,7 @@ export const parseLinkHeader = (header) => { const links = {}; // Parse each part into a named link - for(let i=0; i<parts.length; i++) { + for (let i = 0; i < parts.length; i++) { const section = parts[i].split(';'); if (section.length !== 2) { throw new Error("section could not be split on ';'"); @@ -49,7 +49,9 @@ export const parseBaseUrl = (url) => { */ export const stringListToSelect2DataArray = (list) => { let data = []; - list.forEach((item) => {data.push({id: item, text: item});}); + list.forEach((item) => { + data.push({id: item, text: item}); + }); return data; }; @@ -63,7 +65,7 @@ export const stringListToSelect2DataArray = (list) => { export const base64EncodeUnicode = (str) => { // First we escape the string using encodeURIComponent to get the UTF-8 encoding of the characters, // then we convert the percent encodings into raw bytes, and finally feed it to btoa() function. - const utf8Bytes = encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { + const utf8Bytes = encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { return String.fromCharCode('0x' + p1); }); @@ -89,9 +91,9 @@ export const base64EncodeUnicode = (str) => { * custom tags with an error message so the user gets some feedback instead of * just an empty page. * - * @param {string} name - * @param {Function} constructor - * @param {object} options + * @param {string} name + * @param {Function} constructor + * @param {object} options */ export const defineCustomElement = (name, constructor, options) => { // In case the constructor is already defined just do nothing @@ -99,13 +101,20 @@ export const defineCustomElement = (name, constructor, options) => { return true; } // Checks taken from https://github.com/webcomponents/webcomponentsjs/blob/master/webcomponents-loader.js - if (!('attachShadow' in Element.prototype && 'getRootNode' in Element.prototype && window.customElements)) { + if ( + !( + 'attachShadow' in Element.prototype && + 'getRootNode' in Element.prototype && + window.customElements + ) + ) { var elements = document.getElementsByTagName(name); - for(var i=0; i < elements.length; i++) { - elements[i].innerHTML = "<span style='border: 1px solid red; font-size: 0.8em; " - + "opacity: 0.5; padding: 0.2em;'>☹ Your browser is not supported ☹</span>"; + for (var i = 0; i < elements.length; i++) { + elements[i].innerHTML = + "<span style='border: 1px solid red; font-size: 0.8em; " + + "opacity: 0.5; padding: 0.2em;'>☹ Your browser is not supported ☹</span>"; } - return false; + return false; } customElements.define(name, constructor, options); return true; @@ -120,10 +129,10 @@ export const defineCustomElement = (name, constructor, options) => { * @returns {string} */ export const makeId = (length) => { - let result = ''; - const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const charactersLength = characters.length; - for ( let i = 0; i < length; i++ ) { + for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } @@ -136,7 +145,9 @@ export const makeId = (length) => { * @param n * @returns {string} */ -export const pad10 = (n) => { return n < 10 ? '0' + n : n; }; +export const pad10 = (n) => { + return n < 10 ? '0' + n : n; +}; /** * Converts a date object or string to a local iso datetime with stripped seconds and timezone for the datetime-local input @@ -149,7 +160,9 @@ export const dateToStrippedIsoDT = (date) => { date = new Date(date); } - return `${date.getFullYear()}-${pad10(date.getMonth()+1)}-${pad10(date.getDate())}T${pad10(date.getHours())}:${pad10(date.getMinutes())}`; + return `${date.getFullYear()}-${pad10(date.getMonth() + 1)}-${pad10(date.getDate())}T${pad10( + date.getHours() + )}:${pad10(date.getMinutes())}`; }; /** @@ -163,7 +176,7 @@ export const dateToInputDateString = (date) => { date = new Date(date); } - return `${date.getFullYear()}-${pad10(date.getMonth()+1)}-${pad10(date.getDate())}`; + return `${date.getFullYear()}-${pad10(date.getMonth() + 1)}-${pad10(date.getDate())}`; }; /** @@ -198,7 +211,6 @@ export const getAssetURL = (pkg, path) => { return new URL(fullPath, new URL('..', import.meta.url).href).href; }; - /** * Poll <fn> every <interval> ms until <timeout> ms * @@ -207,17 +219,17 @@ export const getAssetURL = (pkg, path) => { * @param interval */ export const pollFunc = (fn, timeout, interval) => { - var startTime = (new Date()).getTime(); + var startTime = new Date().getTime(); interval = interval || 1000; (function p() { // don't retry if we took longer than timeout ms - if (((new Date).getTime() - startTime ) > timeout) { + if (new Date().getTime() - startTime > timeout) { return; } // retry until fn() returns true - if (!fn()) { + if (!fn()) { setTimeout(p, interval); } })(); @@ -327,8 +339,8 @@ export async function getMimeTypeOfFile(file) { export const getBaseName = (str) => { let base = String(str).substring(str.lastIndexOf('/') + 1); - if (base.lastIndexOf(".") !== -1) { - base = base.substring(0, base.lastIndexOf(".")); + if (base.lastIndexOf('.') !== -1) { + base = base.substring(0, base.lastIndexOf('.')); } return base; @@ -356,9 +368,11 @@ export const querySlotted = (root, selector) => { let matched = []; slots.forEach((slot) => { - matched = matched.concat(slot.assignedElements().filter((el) => { - return el.matches(selector); - })); + matched = matched.concat( + slot.assignedElements().filter((el) => { + return el.matches(selector); + }) + ); }); return matched; diff --git a/packages/data-table-view/.eslintrc.json b/packages/data-table-view/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/data-table-view/.eslintrc.json +++ b/packages/data-table-view/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/data-table-view/.prettierignore b/packages/data-table-view/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/data-table-view/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/data-table-view/.prettierrc.json b/packages/data-table-view/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/data-table-view/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/data-table-view/assets/datatables/i18n/English.json b/packages/data-table-view/assets/datatables/i18n/English.json index 1752400f70f6f5bd5e206ef53838a3e76a2dad13..abdc8ae9960782f6537b0d769ef6713384bc47c4 100644 --- a/packages/data-table-view/assets/datatables/i18n/English.json +++ b/packages/data-table-view/assets/datatables/i18n/English.json @@ -1,25 +1,23 @@ - - { - "sEmptyTable": "No data available in table", - "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", - "sInfoEmpty": "Showing 0 to 0 of 0 entries", - "sInfoFiltered": "(filtered from _MAX_ total entries)", - "sInfoPostFix": "", - "sInfoThousands": ",", - "sLengthMenu": "Show _MENU_ entries", - "sLoadingRecords": "Loading...", - "sProcessing": "Processing...", - "sSearch": "Search", - "sZeroRecords": "No matching records found", - "oPaginate": { - "sFirst": "First", - "sLast": "Last", - "sNext": "Next", - "sPrevious": "Previous" - }, - "oAria": { - "sSortAscending": ": activate to sort column ascending", - "sSortDescending": ": activate to sort column descending" - } -} \ No newline at end of file + "sEmptyTable": "No data available in table", + "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", + "sInfoEmpty": "Showing 0 to 0 of 0 entries", + "sInfoFiltered": "(filtered from _MAX_ total entries)", + "sInfoPostFix": "", + "sInfoThousands": ",", + "sLengthMenu": "Show _MENU_ entries", + "sLoadingRecords": "Loading...", + "sProcessing": "Processing...", + "sSearch": "Search", + "sZeroRecords": "No matching records found", + "oPaginate": { + "sFirst": "First", + "sLast": "Last", + "sNext": "Next", + "sPrevious": "Previous" + }, + "oAria": { + "sSortAscending": ": activate to sort column ascending", + "sSortDescending": ": activate to sort column descending" + } +} diff --git a/packages/data-table-view/assets/datatables/i18n/German.json b/packages/data-table-view/assets/datatables/i18n/German.json index 6daa69a911f3f994bbd6696a33e232ceb5a09fe0..e8b72d4457cf811656c706b7bcdfae031b275de4 100644 --- a/packages/data-table-view/assets/datatables/i18n/German.json +++ b/packages/data-table-view/assets/datatables/i18n/German.json @@ -1,43 +1,41 @@ - - { - "sEmptyTable": "Keine Daten in der Tabelle vorhanden", - "sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen", - "sInfoEmpty": "Keine Daten vorhanden", - "sInfoFiltered": "(gefiltert von _MAX_ Einträgen)", - "sInfoPostFix": "", - "sInfoThousands": ".", - "sLengthMenu": "_MENU_ Einträge anzeigen", - "sLoadingRecords": "Wird geladen ..", - "sProcessing": "Bitte warten ..", - "sSearch": "Suchen", - "sZeroRecords": "Keine Einträge vorhanden", - "oPaginate": { - "sFirst": "Erste", - "sPrevious": "Zurück", - "sNext": "Nächste", - "sLast": "Letzte" - }, - "oAria": { - "sSortAscending": ": aktivieren, um Spalte aufsteigend zu sortieren", - "sSortDescending": ": aktivieren, um Spalte absteigend zu sortieren" - }, - "select": { - "rows": { - "_": "%d Zeilen ausgewählt", - "0": "", - "1": "1 Zeile ausgewählt" - } - }, - "buttons": { - "print": "Drucken", - "colvis": "Spalten", - "copy": "Kopieren", - "copyTitle": "In Zwischenablage kopieren", - "copyKeys": "Taste <i>ctrl</i> oder <i>\u2318</i> + <i>C</i> um Tabelle<br>in Zwischenspeicher zu kopieren.<br><br>Um abzubrechen die Nachricht anklicken oder Escape drücken.", - "copySuccess": { - "_": "%d Spalten kopiert", - "1": "1 Spalte kopiert" - } - } + "sEmptyTable": "Keine Daten in der Tabelle vorhanden", + "sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen", + "sInfoEmpty": "Keine Daten vorhanden", + "sInfoFiltered": "(gefiltert von _MAX_ Einträgen)", + "sInfoPostFix": "", + "sInfoThousands": ".", + "sLengthMenu": "_MENU_ Einträge anzeigen", + "sLoadingRecords": "Wird geladen ..", + "sProcessing": "Bitte warten ..", + "sSearch": "Suchen", + "sZeroRecords": "Keine Einträge vorhanden", + "oPaginate": { + "sFirst": "Erste", + "sPrevious": "Zurück", + "sNext": "Nächste", + "sLast": "Letzte" + }, + "oAria": { + "sSortAscending": ": aktivieren, um Spalte aufsteigend zu sortieren", + "sSortDescending": ": aktivieren, um Spalte absteigend zu sortieren" + }, + "select": { + "rows": { + "_": "%d Zeilen ausgewählt", + "0": "", + "1": "1 Zeile ausgewählt" + } + }, + "buttons": { + "print": "Drucken", + "colvis": "Spalten", + "copy": "Kopieren", + "copyTitle": "In Zwischenablage kopieren", + "copyKeys": "Taste <i>ctrl</i> oder <i>\u2318</i> + <i>C</i> um Tabelle<br>in Zwischenspeicher zu kopieren.<br><br>Um abzubrechen die Nachricht anklicken oder Escape drücken.", + "copySuccess": { + "_": "%d Spalten kopiert", + "1": "1 Spalte kopiert" + } + } } diff --git a/packages/data-table-view/i18next-scanner.config.js b/packages/data-table-view/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/data-table-view/i18next-scanner.config.js +++ b/packages/data-table-view/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/data-table-view/package.json b/packages/data-table-view/package.json index 5498081347a64d4fc332350d395deaf98067bd43..45df9b95ed97b9a7103c0ba4181aa4b7e2c2573b 100644 --- a/packages/data-table-view/package.json +++ b/packages/data-table-view/package.json @@ -1,65 +1,69 @@ { - "name": "@dbp-toolkit/data-table-view", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/data-table-view", - "version": "0.2.3", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/data-table-view" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "glob": "^7.1.6", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "datatables.net-buttons": "^2.0.0", - "datatables.net-buttons-dt": "^2.0.0", - "datatables.net-dt": "^1.10.20", - "datatables.net-responsive": "^2.2.3", - "datatables.net-responsive-dt": "^2.2.3", - "i18next": "^21.4.2", - "jquery": "^3.4.1", - "jszip": "^3.2.2", - "lit": "^2.0.0" - }, - "scripts": { - "clean": "rm -r 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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/data-table-view", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/data-table-view", + "version": "0.2.3", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/data-table-view" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "glob": "^7.1.6", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "datatables.net-buttons": "^2.0.0", + "datatables.net-buttons-dt": "^2.0.0", + "datatables.net-dt": "^1.10.20", + "datatables.net-responsive": "^2.2.3", + "datatables.net-responsive-dt": "^2.2.3", + "i18next": "^21.4.2", + "jquery": "^3.4.1", + "jszip": "^3.2.2", + "lit": "^2.0.0" + }, + "scripts": { + "clean": "rm -r dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/data-table-view/rollup.config.js b/packages/data-table-view/rollup.config.js index 42fa3dec6efa8496f09f7a00e0ba0b113f0cf95c..83f8240b19118da60340bbfc124b8b12a96e385a 100644 --- a/packages/data-table-view/rollup.config.js +++ b/packages/data-table-view/rollup.config.js @@ -2,33 +2,36 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import urlPlugin from "@rollup/plugin-url"; +import urlPlugin from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build != 'test') ? ['src/dbp-data-table-view.js', 'src/dbp-data-table-view-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-data-table-view.js', 'src/dbp-data-table-view-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, watch: { chokidar: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), @@ -36,24 +39,41 @@ export default (async () => { urlPlugin({ limit: 0, emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: 'assets/*.css', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: 'assets/*.ico', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: 'assets/nomodule.js', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, - {src: await getPackagePath('datatables.net-dt', 'css'), dest: 'dist/' + await getDistPath(pkg.name)}, - {src: await getPackagePath('datatables.net-dt', 'images'), dest: 'dist/' + await getDistPath(pkg.name)}, - {src: await getPackagePath('datatables.net-responsive-dt', 'css'), dest: 'dist/' + await getDistPath(pkg.name)}, - {src: await getPackagePath('datatables.net-buttons-dt', 'css'), dest: 'dist/' + await getDistPath(pkg.name)}, + {src: 'assets/*.css', dest: 'dist/' + (await getDistPath(pkg.name))}, + {src: 'assets/*.ico', dest: 'dist/' + (await getDistPath(pkg.name))}, + {src: 'assets/nomodule.js', dest: 'dist/' + (await getDistPath(pkg.name))}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, + { + src: await getPackagePath('datatables.net-dt', 'css'), + dest: 'dist/' + (await getDistPath(pkg.name)), + }, + { + src: await getPackagePath('datatables.net-dt', 'images'), + dest: 'dist/' + (await getDistPath(pkg.name)), + }, + { + src: await getPackagePath('datatables.net-responsive-dt', 'css'), + dest: 'dist/' + (await getDistPath(pkg.name)), + }, + { + src: await getPackagePath('datatables.net-buttons-dt', 'css'), + dest: 'dist/' + (await getDistPath(pkg.name)), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8003}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8003}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/data-table-view/src/data-table-view.js b/packages/data-table-view/src/data-table-view.js index ccf5f9b532630e11ee9ad6581ae7436785d0ed0d..a8a370fe5debd86a7bb541690c202bd898e5e3de 100644 --- a/packages/data-table-view/src/data-table-view.js +++ b/packages/data-table-view/src/data-table-view.js @@ -15,7 +15,7 @@ import {getIconSVGURL} from '@dbp-toolkit/common'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {name as pkgName} from './../package.json'; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; dt(window, $); resp(window, $); @@ -52,18 +52,18 @@ export class DataTableView extends AdapterLitElement { static get properties() { return { ...super.properties, - lang: { type: String }, - table: { type: Object, attribute: false }, - paging: { type: Boolean }, - searching: { type: Boolean }, - columns: { type: Array, attribute: false }, - columnDefs: { type: Array, attribute: false }, - data: { type: Array, attribute: false }, - cssStyle: { type: String, attribute: false }, - exportable: { type: Boolean }, - exportName: { type: String, attribute: 'export-name' }, - columnSearching: { type: Boolean, attribute: 'column-searching'}, - defaultOrder: { type: Array, attribute: 'default-order'} + lang: {type: String}, + table: {type: Object, attribute: false}, + paging: {type: Boolean}, + searching: {type: Boolean}, + columns: {type: Array, attribute: false}, + columnDefs: {type: Array, attribute: false}, + data: {type: Array, attribute: false}, + cssStyle: {type: String, attribute: false}, + exportable: {type: Boolean}, + exportName: {type: String, attribute: 'export-name'}, + columnSearching: {type: Boolean, attribute: 'column-searching'}, + defaultOrder: {type: Array, attribute: 'default-order'}, }; } @@ -91,8 +91,8 @@ export class DataTableView extends AdapterLitElement { columnSearch(col, str) { this.table.column(col).search(str).draw(); } - columnReduce(col, func, init=0) { - return this.table.column(col, { search: 'applied' }).data().reduce( func, init); + columnReduce(col, func, init = 0) { + return this.table.column(col, {search: 'applied'}).data().reduce(func, init); } on(eventName, func) { this.table.on(eventName, func); @@ -104,8 +104,7 @@ export class DataTableView extends AdapterLitElement { const i18n = this._i18n; if (typeof this.columns === 'undefined' || !this.columns.length) { - if (data.length) - throw new Error('columns not set-up'); + if (data.length) throw new Error('columns not set-up'); return this; } @@ -121,14 +120,18 @@ export class DataTableView extends AdapterLitElement { const tr = document.createElement('tr'); this.columns.forEach(function (element, index) { const th = document.createElement('td'); - if (element !== null - && (typeof element.visible === 'undefined' || element.visible !== false) - && (typeof element.searchable === 'undefined' || element.searchable !== false)) { + if ( + element !== null && + (typeof element.visible === 'undefined' || element.visible !== false) && + (typeof element.searchable === 'undefined' || element.searchable !== false) + ) { const input = document.createElement('input'); input.type = 'text'; input.className = 'column-search-line'; input.id = 'input-col-' + index; - input.placeholder = i18n.t('column-search-placeholder', {fieldName: element.title}); + input.placeholder = i18n.t('column-search-placeholder', { + fieldName: element.title, + }); th.appendChild(input); } tr.appendChild(th); @@ -164,7 +167,7 @@ export class DataTableView extends AdapterLitElement { className: 'button is-small', charset: 'UTF-8', bom: true, - fieldSeparator: this.lang === 'en' ? ',' : ';' + fieldSeparator: this.lang === 'en' ? ',' : ';', }, { extend: 'print', @@ -172,7 +175,7 @@ export class DataTableView extends AdapterLitElement { title: this.exportName, className: 'button is-small', }, - ] + ], }); const dataTableLength = sessionStorage.getItem('dbp-data-table-length'); @@ -183,7 +186,7 @@ export class DataTableView extends AdapterLitElement { } //Save page length in session storage - this.table.on('length.dt', function ( e, settings, len ) { + this.table.on('length.dt', function (e, settings, len) { sessionStorage.setItem('dbp-data-table-length', len); }); @@ -195,29 +198,31 @@ export class DataTableView extends AdapterLitElement { } new $.fn.dataTable.Responsive(this.table, { - details: true + details: true, }); if (this.columnSearching) { - const thisTable = this.table; - const that = this; - this.columns.forEach(function (element, index) { - if (element !== null - && (typeof element.visible === 'undefined' || element.visible !== false) - && (typeof element.searchable === 'undefined' || element.searchable !== false)) { - const input = that.shadowRoot.querySelector('#input-col-' + index); - if (input) { - ['keyup', 'change', 'clear'].forEach(function (event) { - input.addEventListener(event, function () { - const column = thisTable.column(index); - if (column.search() !== input.value) { - column.search(input.value).draw(); - } - }); + const thisTable = this.table; + const that = this; + this.columns.forEach(function (element, index) { + if ( + element !== null && + (typeof element.visible === 'undefined' || element.visible !== false) && + (typeof element.searchable === 'undefined' || element.searchable !== false) + ) { + const input = that.shadowRoot.querySelector('#input-col-' + index); + if (input) { + ['keyup', 'change', 'clear'].forEach(function (event) { + input.addEventListener(event, function () { + const column = thisTable.column(index); + if (column.search() !== input.value) { + column.search(input.value).draw(); + } }); - } + }); } - }); + } + }); } this.table.order(this.defaultOrder); @@ -230,20 +235,25 @@ export class DataTableView extends AdapterLitElement { let languageChange = false; changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { - this._i18n.changeLanguage(this.lang).catch(e => { console.log(e);}); + if (propName === 'lang') { + this._i18n.changeLanguage(this.lang).catch((e) => { + console.log(e); + }); languageChange = true; } }); - this.updateComplete.then(this.set_datatable(this.data, languageChange)).catch(e => { console.log(e);}); + this.updateComplete.then(this.set_datatable(this.data, languageChange)).catch((e) => { + console.log(e); + }); super.update(changedProperties); } static get styles() { // language=css const orderExpandIconOverrides = css` - table.dataTable.dtr-inline.collapsed > tbody > tr[role="row"] > td:first-child::before, table.dataTable.dtr-inline.collapsed > tbody > tr[role="row"] > th:first-child::before { + table.dataTable.dtr-inline.collapsed > tbody > tr[role='row'] > td:first-child::before, + table.dataTable.dtr-inline.collapsed > tbody > tr[role='row'] > th:first-child::before { all: initial; top: 0.7em; left: 0.4em; @@ -261,12 +271,14 @@ export class DataTableView extends AdapterLitElement { content: '+'; } - table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child::before, table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child::before { + table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child::before, + table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child::before { content: '-'; } table.dataTable thead .sorting { - background-image: url('${unsafeCSS(getIconSVGURL('chevron-up'))}'), url('${unsafeCSS(getIconSVGURL('chevron-down'))}'); + background-image: url('${unsafeCSS(getIconSVGURL('chevron-up'))}'), + url('${unsafeCSS(getIconSVGURL('chevron-down'))}'); background-position: 100% 40%, 100% 60%; background-size: 0.5em, 0.5em; } @@ -298,11 +310,11 @@ export class DataTableView extends AdapterLitElement { } .export-btn { - margin-bottom: .6rem; + margin-bottom: 0.6rem; } select { - border-radius: calc(var(--dbp-border-radius)/2); + border-radius: calc(var(--dbp-border-radius) / 2); height: 28px; margin-left: 3px; } @@ -313,7 +325,7 @@ export class DataTableView extends AdapterLitElement { .dataTables_filter input { border-radius: 0; - border:; + border: ; padding: 0.1em; } @@ -329,13 +341,13 @@ export class DataTableView extends AdapterLitElement { let bt_css = commonUtils.getAssetURL(pkgName, 'css/buttons.dataTables.min.css'); return html` - <link rel="stylesheet" href="${dt_css}"> - <link rel="stylesheet" href="${rs_css}"> - <link rel="stylesheet" href="${bt_css}"> + <link rel="stylesheet" href="${dt_css}" /> + <link rel="stylesheet" href="${rs_css}" /> + <link rel="stylesheet" href="${bt_css}" /> <style> ${this.cssStyle} </style> <div><table width="100%"></table></div> `; } -} \ No newline at end of file +} diff --git a/packages/data-table-view/src/dbp-data-table-view-demo.js b/packages/data-table-view/src/dbp-data-table-view-demo.js index 9a68aeff33b25d7c47d8f1dd31c9f92166cf2020..6498102ce54c304b6018820c6263fd4db885feb7 100644 --- a/packages/data-table-view/src/dbp-data-table-view-demo.js +++ b/packages/data-table-view/src/dbp-data-table-view-demo.js @@ -5,7 +5,7 @@ import {css, html} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { @@ -18,18 +18,18 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { static get scopedElements() { return { - 'dbp-data-table-view': DataTableView, - 'dbp-auth-keycloak': AuthKeycloak, - 'dbp-login-button': LoginButton, + 'dbp-data-table-view': DataTableView, + 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-login-button': LoginButton, }; } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - noAuth: { type: Boolean, attribute: 'no-auth' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + noAuth: {type: Boolean, attribute: 'no-auth'}, }; } @@ -37,23 +37,30 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { super.connectedCallback(); const that = this; - this.updateComplete.then(()=> { + this.updateComplete.then(() => { /* First Table: with data */ const vdtv1 = that.shadowRoot.querySelector('#vdtv1'); if (vdtv1 !== null) { const vdtv1_columnDefs = [ - { targets: [3], visible: false }, - { targets: [2], orderData: [3] }, - { targets: [3, 4], searchable: false }, - { targets: [4], sortable: false } + {targets: [3], visible: false}, + {targets: [2], orderData: [3]}, + {targets: [3, 4], searchable: false}, + {targets: [4], sortable: false}, ]; const tbl = []; - for (let i = 0; i<25; ++i) { + for (let i = 0; i < 25; ++i) { tbl.push(this.vdtv_create_row()); } - vdtv1.set_columns([{title:'Bezeichnung'}, {title:'Nummer'}, {title:'Datum'}, null, null]) + vdtv1 + .set_columns([ + {title: 'Bezeichnung'}, + {title: 'Nummer'}, + {title: 'Datum'}, + null, + null, + ]) .set_columnDefs(vdtv1_columnDefs) .set_datatable(tbl) .on('draw', this.vdtv_draw.bind(this)); @@ -65,12 +72,19 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { const vdtv2 = that.shadowRoot.querySelector('#vdtv2'); if (vdtv2 !== null) { const vdtv2_columnDefs = [ - { targets: [3], visible: false }, - { targets: [2], orderData: [3] }, - { targets: [3, 4], searchable: false }, - { targets: [4], sortable: false } + {targets: [3], visible: false}, + {targets: [2], orderData: [3]}, + {targets: [3, 4], searchable: false}, + {targets: [4], sortable: false}, ]; - vdtv2.set_columns([{title:'Bezeichnung-2'}, {title:'Nummer-2'}, {title:'Datum-2'}, null, null]) + vdtv2 + .set_columns([ + {title: 'Bezeichnung-2'}, + {title: 'Nummer-2'}, + {title: 'Datum-2'}, + null, + null, + ]) .set_columnDefs(vdtv2_columnDefs) .set_datatable([]); } @@ -79,20 +93,19 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { */ const vdtv3 = that.shadowRoot.querySelector('#vdtv3'); if (vdtv3 !== null) { - const vdtv3_columnDefs = [ - { targets: [0,1,2], visible: true}, - ]; - vdtv3.set_columns([{title:'City'}, {title:'Zip'}, {title:'Museum'}]) + const vdtv3_columnDefs = [{targets: [0, 1, 2], visible: true}]; + vdtv3 + .set_columns([{title: 'City'}, {title: 'Zip'}, {title: 'Museum'}]) .set_columnDefs(vdtv3_columnDefs) // .set_defaultOrder([[1,"desc"],[2,"asc"]]) .set_datatable([ - { '0': 'Graz', '1': '8020', '2': 'Alte Galerie'}, - { '0': 'Graz', '1': '8020', '2': 'Kunsthaus'}, - { '0': 'Graz', '1': '8010', '2': 'Haus der Wissenschaft'}, - { '0': 'Graz', '1': '8010', '2': 'Landeszeughaus'}, - { '0': 'Linz', '1': '4020', '2': 'Lentos Kunstmuseum'}, - { '0': 'Linz', '1': '4020', '2': 'Ars Electronica Center'}, - { '0': 'Wien', '1': '1010', '2': 'Museum für Plansprachen'}, + {0: 'Graz', 1: '8020', 2: 'Alte Galerie'}, + {0: 'Graz', 1: '8020', 2: 'Kunsthaus'}, + {0: 'Graz', 1: '8010', 2: 'Haus der Wissenschaft'}, + {0: 'Graz', 1: '8010', 2: 'Landeszeughaus'}, + {0: 'Linz', 1: '4020', 2: 'Lentos Kunstmuseum'}, + {0: 'Linz', 1: '4020', 2: 'Ars Electronica Center'}, + {0: 'Wien', 1: '1010', 2: 'Museum für Plansprachen'}, ]); } }); @@ -100,7 +113,7 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -109,16 +122,19 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { } vdtv_create_row() { - const str = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); - const day = Math.floor(Math.random()*(31-1) + 1); - const month = Math.floor(Math.random()*(12-1) + 1); - const year = Math.floor(Math.random()*(2019-2016) + 2016); + const str = Math.random() + .toString(36) + .replace(/[^a-z]+/g, '') + .substr(0, 5); + const day = Math.floor(Math.random() * (31 - 1) + 1); + const month = Math.floor(Math.random() * (12 - 1) + 1); + const year = Math.floor(Math.random() * (2019 - 2016) + 2016); return [ str, Math.floor(1000 * Math.random()), '' + day + '.' + month + '.' + year, '' + year + '-' + month + '-' + day, - '<button class=\'button is-small\' onclick="alert(\'' + str + ' clicked\');">OK</button>' + "<button class='button is-small' onclick=\"alert('" + str + ' clicked\');">OK</button>', ]; } @@ -140,14 +156,24 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button>` : html` - <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" - url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" - client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> - <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> - </div> - `; + return this.noAuth + ? html` + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + ` + : html` + <div class="container"> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + url="https://auth-dev.tugraz.at/auth" + realm="tugraz-vpu" + client-id="auth-dev-mw-frontend-local" + try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + </div> + `; } static get styles() { @@ -170,9 +196,14 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { /* from BULMA.CSS */ .content h1 { font-size: 2em; - margin-bottom: .5em; + margin-bottom: 0.5em; } - .content h1, .content h2, .content h3, .content h4, .content h5, .content h6 { + .content h1, + .content h2, + .content h3, + .content h4, + .content h5, + .content h6 { color: var(--dbp-text); font-weight: 600; line-height: 1.125; @@ -191,11 +222,11 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { } .content table th { border: 1px solid #dbdbdb; - padding: .5em .75em; + padding: 0.5em 0.75em; vertical-align: top; } .content table td { - padding: .5em .75em; + padding: 0.5em 0.75em; vertical-align: top; } </style> @@ -207,26 +238,38 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { ${this.getAuthComponentHtml()} <div class="content"> <h4>DataTable: with data, paging and searching AND exportable</h4> - <div class="box"> - <label for="id-sum">Sum of column <b>Number</b> is</label> - <input type="text" readonly value="" name="sum" id="id-sum"> - <dbp-data-table-view paging searching column-searching - default-order='[1,"asc"]' - exportable export-name="Demo Export" - lang="${this.lang}" id="vdtv1"></dbp-data-table-view> + <div class="box"> + <label for="id-sum"> + Sum of column + <b>Number</b> + is + </label> + <input type="text" readonly value="" name="sum" id="id-sum" /> + <dbp-data-table-view + paging + searching + column-searching + default-order='[1,"asc"]' + exportable + export-name="Demo Export" + lang="${this.lang}" + id="vdtv1"></dbp-data-table-view> </div> <h4>DataTable: no data, no paging, no searching</h4> <div class="box"> - <button class="button is-small" @click="${this.vdtv2_add_rows}">add something...</button> + <button class="button is-small" @click="${this.vdtv2_add_rows}"> + add something... + </button> <dbp-data-table-view lang="${this.lang}" id="vdtv2"></dbp-data-table-view> </div> <h4>DataTable: ordering by column 'zip' desc, 'museum' asc</h4> <div class="box"> - <dbp-data-table-view default-order='[[1,"desc"],[2,"asc"]]' - lang="${this.lang}" id="vdtv3"></dbp-data-table-view> + <dbp-data-table-view + default-order='[[1,"desc"],[2,"asc"]]' + lang="${this.lang}" + id="vdtv3"></dbp-data-table-view> </div> </div> - </section> `; } diff --git a/packages/data-table-view/src/demo.js b/packages/data-table-view/src/demo.js index 84cdedf3fa73674bfd32775e6e1bbcb847543e19..b1e7bdeb70dade52498095691a1f1d6bc59c730b 100644 --- a/packages/data-table-view/src/demo.js +++ b/packages/data-table-view/src/demo.js @@ -1 +1 @@ -import './dbp-data-table-view-demo.js'; \ No newline at end of file +import './dbp-data-table-view-demo.js'; diff --git a/packages/data-table-view/src/i18n.js b/packages/data-table-view/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/data-table-view/src/i18n.js +++ b/packages/data-table-view/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/data-table-view/src/i18n/de/translation.json b/packages/data-table-view/src/i18n/de/translation.json index ed90a81bded1457b6812b1c1de10aa6e71d6b272..175e60ae4bd6cbc9c8d5ef0b0a119815249ba07b 100644 --- a/packages/data-table-view/src/i18n/de/translation.json +++ b/packages/data-table-view/src/i18n/de/translation.json @@ -1,6 +1,6 @@ { - "print": "Drucken", - "export-excel": "Excel Export", - "export-csv": "CSV Export", - "column-search-placeholder": "Nach {{fieldName}} suchen" + "print": "Drucken", + "export-excel": "Excel Export", + "export-csv": "CSV Export", + "column-search-placeholder": "Nach {{fieldName}} suchen" } diff --git a/packages/data-table-view/src/i18n/en/translation.json b/packages/data-table-view/src/i18n/en/translation.json index 0c0acdb39f4d0c3af06998f9cddfb426c23e2f21..b4cb3d15702439d46cc4daba32552f5c97a41d44 100644 --- a/packages/data-table-view/src/i18n/en/translation.json +++ b/packages/data-table-view/src/i18n/en/translation.json @@ -1,6 +1,6 @@ { - "print": "Print", - "export-excel": "Excel Export", - "export-csv": "CSV Export", - "column-search-placeholder": "Search for {{fieldName}}" + "print": "Print", + "export-excel": "Excel Export", + "export-csv": "CSV Export", + "column-search-placeholder": "Search for {{fieldName}}" } diff --git a/packages/data-table-view/src/index.js b/packages/data-table-view/src/index.js index f785a8147ec8ff6acc9cd6a82bb2e3af280e9213..839e4b0f055d938e798c53dc9277803d2e227a43 100644 --- a/packages/data-table-view/src/index.js +++ b/packages/data-table-view/src/index.js @@ -1,3 +1,3 @@ import {DataTableView} from './data-table-view.js'; -export {DataTableView}; \ No newline at end of file +export {DataTableView}; diff --git a/packages/data-table-view/test/unit.js b/packages/data-table-view/test/unit.js index 289c8bff8e47bb3c40d8961d17bdf38b8053dca0..f33bf47bade6895da8fc2032bf2b86420118da70 100644 --- a/packages/data-table-view/test/unit.js +++ b/packages/data-table-view/test/unit.js @@ -4,37 +4,37 @@ import '../src/dbp-data-table-view'; import '../src/dbp-data-table-view-demo'; suite('dbp-data-table-view basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-data-table-view'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-data-table-view'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert(node.shadowRoot !== undefined); - }); + test('should render', () => { + assert(node.shadowRoot !== undefined); + }); }); suite('dbp-data-table-view-demo basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-data-table-view-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-data-table-view-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert(node.shadowRoot !== undefined); - }); + test('should render', () => { + assert(node.shadowRoot !== undefined); + }); }); diff --git a/packages/file-handling/.eslintrc.json b/packages/file-handling/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/file-handling/.eslintrc.json +++ b/packages/file-handling/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/file-handling/.prettierignore b/packages/file-handling/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/file-handling/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/file-handling/.prettierrc.json b/packages/file-handling/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/file-handling/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/file-handling/i18next-scanner.config.js b/packages/file-handling/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/file-handling/i18next-scanner.config.js +++ b/packages/file-handling/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/file-handling/package.json b/packages/file-handling/package.json index 04b49ae1e97c09cc816ef6173429036cd9fcd757..4b8374b2a2cd88e71f6361c91c9e0a6cd9824a7e 100644 --- a/packages/file-handling/package.json +++ b/packages/file-handling/package.json @@ -1,62 +1,66 @@ { - "name": "@dbp-toolkit/file-handling", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/file-handling", - "version": "0.2.7", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/file-handling" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.0.2", - "@rollup/plugin-node-resolve": "^13.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.0", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "file-saver": "^2.0.2", - "i18next": "^21.4.2", - "jose": "^4.0.0", - "jszip": "^3.5.0", - "lit": "^2.0.0", - "material-design-icons-svg": "^3.0.0", - "tabulator-tables": "^4.8.4", - "webdav": "4.8.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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/file-handling", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/file-handling", + "version": "0.2.7", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/file-handling" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.0.2", + "@rollup/plugin-node-resolve": "^13.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.0", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "file-saver": "^2.0.2", + "i18next": "^21.4.2", + "jose": "^4.0.0", + "jszip": "^3.5.0", + "lit": "^2.0.0", + "material-design-icons-svg": "^3.0.0", + "tabulator-tables": "^4.8.4", + "webdav": "4.8.0" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/file-handling/rollup.config.js b/packages/file-handling/rollup.config.js index 08d780b0e123fe91d18fc9c42a91b79351455b9b..ca215dbbfc023b25f170fb4840563634d2372008 100644 --- a/packages/file-handling/rollup.config.js +++ b/packages/file-handling/rollup.config.js @@ -2,47 +2,64 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; -import path from "path"; +import path from 'path'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +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 (async () => { return { - input: (build !== 'test') ? ['src/demo.js', 'src/dbp-file-source.js', 'src/dbp-file-sink.js', 'src/dbp-clipboard.js', 'src/dbp-nextcloud-file-picker.js'] : glob.sync('test/**/*.js'), + input: + build !== 'test' + ? [ + 'src/demo.js', + 'src/dbp-file-source.js', + 'src/dbp-file-sink.js', + 'src/dbp-clipboard.js', + 'src/dbp-nextcloud-file-picker.js', + ] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve({browser: true}), commonjs(), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, {src: 'assets/favicon.ico', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, - {src: await getPackagePath('tabulator-tables', 'dist/css'), dest: 'dist/' + await getDistPath(pkg.name, 'tabulator-tables')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, + { + src: await getPackagePath('tabulator-tables', 'dist/css'), + dest: 'dist/' + (await getDistPath(pkg.name, 'tabulator-tables')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/file-handling/src/clipboard.js b/packages/file-handling/src/clipboard.js index 363f57806effcb351b0d03f3011863690416b3c4..e9dbb324757ccfc3df56e73cde1732c9d37fc306 100644 --- a/packages/file-handling/src/clipboard.js +++ b/packages/file-handling/src/clipboard.js @@ -5,19 +5,18 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import * as fileHandlingStyles from '@dbp-toolkit/file-handling/src/styles'; import {Icon} from '@dbp-toolkit/common'; -import Tabulator from "tabulator-tables"; -import {humanFileSize} from "@dbp-toolkit/common/i18next"; -import {name as pkgName} from "@dbp-toolkit/file-handling/package.json"; -import {send} from "@dbp-toolkit/common/notification"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import Tabulator from 'tabulator-tables'; +import {humanFileSize} from '@dbp-toolkit/common/i18next'; +import {name as pkgName} from '@dbp-toolkit/file-handling/package.json'; +import {send} from '@dbp-toolkit/common/notification'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; import {classMap} from 'lit/directives/class-map.js'; -const MODE_TABLE_ONLY = "table-only"; -const MODE_FILE_SINK = "file-sink"; -const MODE_FILE_SOURCE = "file-source"; +const MODE_TABLE_ONLY = 'table-only'; +const MODE_FILE_SINK = 'file-sink'; +const MODE_FILE_SOURCE = 'file-source'; export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { - constructor() { super(); this._i18n = createInstance(); @@ -33,18 +32,22 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { this.countUploadFiles = 0; this.buttonsDisabled = false; - this.nextcloudWebAppPasswordURL = ""; - this.nextcloudWebDavURL = ""; - this.nextcloudName = ""; - this.nextcloudFileURL = ""; + this.nextcloudWebAppPasswordURL = ''; + this.nextcloudWebDavURL = ''; + this.nextcloudName = ''; + this.nextcloudFileURL = ''; this.nextcloudStoreSession = false; this.authInfo = ''; this.allowNesting = false; // To avoid a cyclic dependency - import('./file-sink').then(({ FileSink }) => this.defineScopedElement('dbp-file-sink', FileSink)); - import('./file-source').then(({ FileSource }) => this.defineScopedElement('dbp-file-source', FileSource)); + import('./file-sink').then(({FileSink}) => + this.defineScopedElement('dbp-file-sink', FileSink) + ); + import('./file-source').then(({FileSource}) => + this.defineScopedElement('dbp-file-source', FileSource) + ); this.mode = MODE_TABLE_ONLY; } @@ -58,43 +61,47 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, - allowedMimeTypes: { type: String, attribute: 'allowed-mime-types' }, - clipboardSelectBtnDisabled: { type: Boolean }, - clipboardFiles: {type: Object, attribute: 'clipboard-files' }, - filesToSave: {type: Array, attribute: 'files-to-save' }, - numberOfSelectedFiles: {type: Number, attribute: false }, + lang: {type: String}, + allowedMimeTypes: {type: String, attribute: 'allowed-mime-types'}, + clipboardSelectBtnDisabled: {type: Boolean}, + clipboardFiles: {type: Object, attribute: 'clipboard-files'}, + filesToSave: {type: Array, attribute: 'files-to-save'}, + numberOfSelectedFiles: {type: Number, attribute: false}, enabledTargets: {type: String, attribute: 'enabled-targets'}, - buttonsDisabled: {type: Boolean }, + buttonsDisabled: {type: Boolean}, - nextcloudWebAppPasswordURL: { type: String, attribute: 'nextcloud-auth-url' }, - nextcloudWebDavURL: { type: String, attribute: 'nextcloud-web-dav-url' }, - nextcloudName: { type: String, attribute: 'nextcloud-name' }, - nextcloudFileURL: { type: String, attribute: 'nextcloud-file-url' }, + nextcloudWebAppPasswordURL: {type: String, attribute: 'nextcloud-auth-url'}, + nextcloudWebDavURL: {type: String, attribute: 'nextcloud-web-dav-url'}, + nextcloudName: {type: String, attribute: 'nextcloud-name'}, + nextcloudFileURL: {type: String, attribute: 'nextcloud-file-url'}, nextcloudAuthInfo: {type: String, attribute: 'nextcloud-auth-info'}, nextcloudStoreSession: {type: Boolean, attribute: 'nextcloud-store-session'}, mode: {type: String, attribute: 'mode'}, - allowNesting: {type: Boolean, attribute: 'allow-nesting' }, + allowNesting: {type: Boolean, attribute: 'allow-nesting'}, }; } _(selector) { - return this.shadowRoot === null ? this.querySelector(selector) : this.shadowRoot.querySelector(selector); + return this.shadowRoot === null + ? this.querySelector(selector) + : this.shadowRoot.querySelector(selector); } _a(selector) { - return this.shadowRoot === null ? this.querySelectorAll(selector) : this.shadowRoot.querySelectorAll(selector); + return this.shadowRoot === null + ? this.querySelectorAll(selector) + : this.shadowRoot.querySelectorAll(selector); } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); break; - case "clipboardFiles": + case 'clipboardFiles': this.generateClipboardTable(); break; @@ -106,105 +113,107 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { async firstUpdated() { // Give the browser a chance to paint await new Promise((r) => setTimeout(r, 0)); - if (this._("#select_all")) { + if (this._('#select_all')) { let boundSelectHandler = this.selectAllFiles.bind(this); - this._("#select_all").addEventListener('click', boundSelectHandler); + this._('#select_all').addEventListener('click', boundSelectHandler); } } toggleCollapse(e) { const table = this.tabulatorTable; - setTimeout(function() { + setTimeout(function () { table.redraw(); }, 0); } - connectedCallback() { const i18n = this._i18n; super.connectedCallback(); const that = this; this.updateComplete.then(() => { - // see: http://tabulator.info/docs/4.7 - this.tabulatorTable = new Tabulator(this._("#clipboard-content-table"), {//if you delete the wrapper around the table you need to set a heigh here - layout: "fitColumns", + this.tabulatorTable = new Tabulator(this._('#clipboard-content-table'), { + //if you delete the wrapper around the table you need to set a heigh here + layout: 'fitColumns', selectable: true, - selectableRangeMode: "drag", - responsiveLayout:"collapse", - responsiveLayoutCollapseStartOpen:false, + selectableRangeMode: 'drag', + responsiveLayout: 'collapse', + responsiveLayoutCollapseStartOpen: false, resizableColumns: false, - placeholder: i18n.t("clipboard.no-data"), + placeholder: i18n.t('clipboard.no-data'), columns: [ { width: 32, minWidth: 32, - align: "center", + align: 'center', resizable: false, headerSort: false, - formatter: "responsiveCollapse" + formatter: 'responsiveCollapse', }, { - title: '<label class="button-container select-all-icon">' + + title: + '<label class="button-container select-all-icon">' + '<input type="checkbox" id="select_all" name="select_all" value="select_all">' + '<span class="checkmark" id="select_all_checkmark"></span>' + '</label>', - field: "type", - align: "center", + field: 'type', + align: 'center', headerSort: false, width: 50, responsive: 1, formatter: (cell, formatterParams, onRendered) => { - const icon_tag = that.getScopedTagName("dbp-icon"); + const icon_tag = that.getScopedTagName('dbp-icon'); let icon = `<${icon_tag} name="empty-file" class="nextcloud-picker-icon"></${icon_tag}>`; return icon; - } + }, }, { - title: i18n.t("clipboard.file-name"), + title: i18n.t('clipboard.file-name'), responsive: 0, widthGrow: 5, minWidth: 150, - field: "name", - sorter: "alphanum", + field: 'name', + sorter: 'alphanum', formatter: (cell) => { let data = cell.getRow().getData(); if (data.edit) { - cell.getElement().classList.add("fokus-edit"); + cell.getElement().classList.add('fokus-edit'); } return cell.getValue(); - } + }, }, { - title: i18n.t("clipboard.file-size"), + title: i18n.t('clipboard.file-size'), responsive: 4, widthGrow: 1, minWidth: 84, - field: "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: i18n.t("clipboard.file-type"), + title: i18n.t('clipboard.file-type'), responsive: 2, widthGrow: 1, minWidth: 58, - field: "type", + field: 'type', formatter: (cell, formatterParams, onRendered) => { if (typeof cell.getValue() === 'undefined') { - return ""; + return ''; } const [, fileSubType] = cell.getValue().split('/'); return fileSubType; - } + }, }, { - title: i18n.t("clipboard.file-mod"), + title: i18n.t('clipboard.file-mod'), responsive: 3, widthGrow: 1, minWidth: 150, - field: "lastModified", + field: 'lastModified', sorter: (a, b, aRow, bRow, column, dir, sorterParams) => { const a_timestamp = Date.parse(a); const b_timestamp = Date.parse(b); @@ -213,28 +222,34 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { formatter: function (cell, formatterParams, onRendered) { const timestamp = new Date(cell.getValue()); const year = timestamp.getFullYear(); - const month = ("0" + (timestamp.getMonth() + 1)).slice(-2); - const date = ("0" + timestamp.getDate()).slice(-2); - const hours = ("0" + timestamp.getHours()).slice(-2); - const minutes = ("0" + timestamp.getMinutes()).slice(-2); - return date + "." + month + "." + year + " " + hours + ":" + minutes; - } + const month = ('0' + (timestamp.getMonth() + 1)).slice(-2); + const date = ('0' + timestamp.getDate()).slice(-2); + const hours = ('0' + timestamp.getHours()).slice(-2); + const minutes = ('0' + timestamp.getMinutes()).slice(-2); + return date + '.' + month + '.' + year + ' ' + hours + ':' + minutes; + }, }, - {title: "file", field: "file", visible: false} + {title: 'file', field: 'file', visible: false}, ], initialSort: [ - {column: "name", dir: "asc"}, - {column: "type", dir: "asc"}, + {column: 'name', dir: 'asc'}, + {column: 'type', dir: 'asc'}, ], rowClick: (e, row) => { - this.numberOfSelectedFiles = this.tabulatorTable !== null ? this.tabulatorTable.getSelectedRows().length : 0; - if (this.tabulatorTable !== null - && this.tabulatorTable.getSelectedRows().length === this.tabulatorTable.getRows().filter(row => this.checkFileType(row.getData())).length) { - this._("#select_all").checked = true; - + this.numberOfSelectedFiles = + this.tabulatorTable !== null + ? this.tabulatorTable.getSelectedRows().length + : 0; + if ( + this.tabulatorTable !== null && + this.tabulatorTable.getSelectedRows().length === + this.tabulatorTable + .getRows() + .filter((row) => this.checkFileType(row.getData())).length + ) { + this._('#select_all').checked = true; } else { - this._("#select_all").checked = false; - + this._('#select_all').checked = false; } }, rowSelectionChanged: (data, rows) => { @@ -244,28 +259,40 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { this.clipboardSelectBtnDisabled = true; } - if (this._("#select_all_checkmark")) { - this._("#select_all_checkmark").title = this.checkAllSelected() ? i18n.t('clipboard.select-nothing') : i18n.t('clipboard.select-all'); + if (this._('#select_all_checkmark')) { + this._('#select_all_checkmark').title = this.checkAllSelected() + ? i18n.t('clipboard.select-nothing') + : i18n.t('clipboard.select-all'); } }, dataLoaded: () => { if (this.tabulatorTable !== null) { const that = this; - setTimeout(function(){ + setTimeout(function () { if (that._('.tabulator-responsive-collapse-toggle-open')) { - that._a('.tabulator-responsive-collapse-toggle-open').forEach(element => element.addEventListener("click", that.toggleCollapse.bind(that))); + that._a('.tabulator-responsive-collapse-toggle-open').forEach( + (element) => + element.addEventListener( + 'click', + that.toggleCollapse.bind(that) + ) + ); } if (that._('.tabulator-responsive-collapse-toggle-close')) { - that._a('.tabulator-responsive-collapse-toggle-close').forEach(element => element.addEventListener("click", that.toggleCollapse.bind(that))); + that._a('.tabulator-responsive-collapse-toggle-close').forEach( + (element) => + element.addEventListener( + 'click', + that.toggleCollapse.bind(that) + ) + ); } }, 0); } - }, }); that.generateClipboardTable(); - }); //Register only one beforeunload Event for the clipboard warning if (!window.clipboardWarning) { @@ -274,10 +301,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { } } - - disconnectedCallback() { - //We doesn't want to deregister this event, because we want to use this event over activities //window.removeEventListener('beforeunload', this._onReceiveBeforeUnload); super.disconnectedCallback(); @@ -290,10 +314,18 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { selectAllFiles() { let allSelected = this.checkAllSelected(); if (allSelected) { - this.tabulatorTable.getSelectedRows().forEach(row => row.deselect()); + this.tabulatorTable.getSelectedRows().forEach((row) => row.deselect()); this.numberOfSelectedFiles = 0; } else { - this.tabulatorTable.selectRow(this.tabulatorTable.getRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes))); + this.tabulatorTable.selectRow( + this.tabulatorTable + .getRows() + .filter( + (row) => + row.getData().type != 'directory' && + this.checkFileType(row.getData(), this.allowedMimeTypes) + ) + ); this.numberOfSelectedFiles = this.tabulatorTable.getSelectedRows().length; } } @@ -306,7 +338,13 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { */ checkAllSelected() { if (this.tabulatorTable) { - let maxSelected = this.tabulatorTable.getRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes)).length; + let maxSelected = this.tabulatorTable + .getRows() + .filter( + (row) => + row.getData().type != 'directory' && + this.checkFileType(row.getData(), this.allowedMimeTypes) + ).length; let selected = this.tabulatorTable.getSelectedRows().length; if (selected === maxSelected) { return true; @@ -315,7 +353,6 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { return false; } - /** * Check mime type of a file, returns true if this.allowedMimeTypes contains the mime type of the file * @@ -323,8 +360,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * @returns {boolean} */ checkFileType(file) { - if (this.allowedMimeTypes === '') - return true; + if (this.allowedMimeTypes === '') return true; // check if file is allowed const [fileMainType, fileSubType] = file.type.split('/'); const mimeTypes = this.allowedMimeTypes.split(','); @@ -332,11 +368,16 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { mimeTypes.forEach((str) => { const [mainType, subType] = str.split('/'); - deny = deny && ((mainType !== '*' && mainType !== fileMainType) || (subType !== '*' && subType !== fileSubType)); + deny = + deny && + ((mainType !== '*' && mainType !== fileMainType) || + (subType !== '*' && subType !== fileSubType)); }); if (deny) { - console.log(`mime type ${file.type} of file '${file.name}' is not compatible with ${this.allowedMimeTypes}`); + console.log( + `mime type ${file.type} of file '${file.name}' is not compatible with ${this.allowedMimeTypes}` + ); return false; } return true; @@ -356,7 +397,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { size: this.clipboardFiles.files[i].size, type: this.clipboardFiles.files[i].type, lastModified: this.clipboardFiles.files[i].lastModified, - file: this.clipboardFiles.files[i] + file: this.clipboardFiles.files[i], }; } @@ -365,8 +406,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { this.tabulatorTable.setData(data); } } - if (this._("#select_all")) { - this._("#select_all").checked = false; + if (this._('#select_all')) { + this._('#select_all').checked = false; } } @@ -377,26 +418,28 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { */ async sendClipboardFiles(files) { const i18n = this._i18n; - for (let i = 0; i < files.length; i ++) { + for (let i = 0; i < files.length; i++) { await this.sendFileEvent(files[i].file); } this.tabulatorTable.deselectRow(); send({ - "summary": i18n.t('clipboard.saved-files-title', {count: files.length}), - "body": i18n.t('clipboard.saved-files-body', {count: files.length}), - "type": "success", - "timeout": 5, + summary: i18n.t('clipboard.saved-files-title', {count: files.length}), + body: i18n.t('clipboard.saved-files-body', {count: files.length}), + type: 'success', + timeout: 5, }); } async sendFileEvent(file) { - const data = {"file": file, "data": file}; - const event = new CustomEvent("dbp-clipboard-file-picker-file-downloaded", - { "detail": data, bubbles: true, composed: true }); + const data = {file: file, data: file}; + const event = new CustomEvent('dbp-clipboard-file-picker-file-downloaded', { + detail: data, + bubbles: true, + composed: true, + }); this.dispatchEvent(event); } - /** * Decides if the "beforeunload" event needs to be canceled * @@ -413,15 +456,17 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { // we need to handle custom events ourselves if (event.target && event.target.activeElement && event.target.activeElement.nodeName) { send({ - "summary": i18n.t('clipboard.file-warning'), - "body": i18n.t('clipboard.file-warning-body', {count: this.clipboardFiles.files.length}), - "type": "warning", - "timeout": 5, + summary: i18n.t('clipboard.file-warning'), + body: i18n.t('clipboard.file-warning-body', { + count: this.clipboardFiles.files.length, + }), + type: 'warning', + timeout: 5, }); if (!event.isTrusted) { // note that this only works with custom event since calls of "confirm" are ignored // in the non-custom event, see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event - const result = confirm("##carefulsaveialuge"); + const result = confirm('##carefulsaveialuge'); // don't stop the page leave if the user wants to leave if (result) { return; @@ -439,8 +484,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * * @param event */ - saveFilesToClipboardEvent(event) - { + saveFilesToClipboardEvent(event) { //save it let data = {}; let files = []; @@ -452,10 +496,12 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { } this.filesToSave = files; if (files && files.length !== 0) { - data = {"files": files}; + data = {files: files}; this.sendSetPropertyEvent('clipboard-files', data); - const event = new CustomEvent("dbp-clipboard-file-picker-file-uploaded", - { bubbles: true, composed: true }); + const event = new CustomEvent('dbp-clipboard-file-picker-file-uploaded', { + bubbles: true, + composed: true, + }); this.dispatchEvent(event); } @@ -472,8 +518,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * Saves all files from this.filesToSave in clipboard and throws a notification * */ - saveFilesToClipboard() - { + saveFilesToClipboard() { const i18n = this._i18n; //save it @@ -486,16 +531,18 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { files = files.concat(this.filesToSave); } if (this.filesToSave && this.filesToSave.length !== 0) { - data = {"files": files}; + data = {files: files}; this.sendSetPropertyEvent('clipboard-files', data); - const event = new CustomEvent("dbp-clipboard-file-picker-file-uploaded", - { bubbles: true, composed: true }); + const event = new CustomEvent('dbp-clipboard-file-picker-file-uploaded', { + bubbles: true, + composed: true, + }); this.dispatchEvent(event); send({ - "summary": i18n.t('clipboard.saved-files-title', {count: this.filesToSave.length}), - "body": i18n.t('clipboard.saved-files-body', {count: this.filesToSave.length}), - "type": "success", - "timeout": 5, + summary: i18n.t('clipboard.saved-files-title', {count: this.filesToSave.length}), + body: i18n.t('clipboard.saved-files-body', {count: this.filesToSave.length}), + type: 'success', + timeout: 5, }); } } @@ -508,10 +555,10 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { finishedSaveFilesToClipboard(event) { const i18n = this._i18n; send({ - "summary": i18n.t('clipboard.saved-files-title', {count: event.detail.count}), - "body": i18n.t('clipboard.saved-files-body', {count: event.detail.count}), - "type": "success", - "timeout": 5, + summary: i18n.t('clipboard.saved-files-title', {count: event.detail.count}), + body: i18n.t('clipboard.saved-files-body', {count: event.detail.count}), + type: 'success', + timeout: 5, }); } @@ -520,18 +567,18 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * */ openFileSink() { - const fileSink = this._("#file-sink-clipboard"); - if ( fileSink ) { + const fileSink = this._('#file-sink-clipboard'); + if (fileSink) { let files = Array(); if (this.tabulatorTable.getSelectedData().length > 0) { - this.tabulatorTable.getSelectedData().forEach(fileObject => { + this.tabulatorTable.getSelectedData().forEach((fileObject) => { files.push(fileObject.file); }); } else { files = this.clipboardFiles.files; } - this._("#file-sink-clipboard").files = Object.create(files); - this._("#file-sink-clipboard").openDialog(); + this._('#file-sink-clipboard').files = Object.create(files); + this._('#file-sink-clipboard').openDialog(); } } @@ -540,9 +587,9 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * */ openFileSource() { - const fileSource = this._("#file-source-clipboard"); + const fileSource = this._('#file-source-clipboard'); if (fileSource) { - this._("#file-source-clipboard").openDialog(); + this._('#file-source-clipboard').openDialog(); } } @@ -556,26 +603,24 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { if (this.tabulatorTable && this.tabulatorTable.getSelectedData().length > 0) { let count = this.tabulatorTable.getSelectedData().length; this.tabulatorTable.deleteRow(this.tabulatorTable.getSelectedRows()); - let data = {"files": []}; - this.tabulatorTable.getRows().forEach(row => - data.files.push( row.getData().file ) - ); + let data = {files: []}; + this.tabulatorTable.getRows().forEach((row) => data.files.push(row.getData().file)); this.sendSetPropertyEvent('clipboard-files', data); send({ - "summary": i18n.t('clipboard.clear-count-clipboard-title', {count: count}), - "body": i18n.t('clipboard.clear-count-clipboard-body', {count: count}), - "type": "success", - "timeout": 5, + summary: i18n.t('clipboard.clear-count-clipboard-title', {count: count}), + body: i18n.t('clipboard.clear-count-clipboard-body', {count: count}), + type: 'success', + timeout: 5, }); this.numberOfSelectedFiles = 0; } else { - let data = {"files": []}; + let data = {files: []}; this.sendSetPropertyEvent('clipboard-files', data); send({ - "summary": i18n.t('clipboard.clear-clipboard-title'), - "body": i18n.t('clipboard.clear-clipboard-body'), - "type": "success", - "timeout": 5, + summary: i18n.t('clipboard.clear-clipboard-title'), + body: i18n.t('clipboard.clear-clipboard-body'), + type: 'success', + timeout: 5, }); } } @@ -589,63 +634,99 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { */ getAdditionalButtons() { const i18n = this._i18n; - let buttonsAreDisabled = this.clipboardFiles.files.length === 0 ? true : this.clipboardSelectBtnDisabled; + let buttonsAreDisabled = + this.clipboardFiles.files.length === 0 ? true : this.clipboardSelectBtnDisabled; buttonsAreDisabled = this.buttonsDisabled ? true : buttonsAreDisabled; return html` <div class="flex-container additional-button-container"> - <div class="btn-flex-container-mobile"> - <button id="clipboard-add-files-button" @click="${() => { this.openFileSource(); }}" - class="button ${classMap({hidden: this.mode === MODE_FILE_SINK || this.mode === MODE_FILE_SOURCE})}" title="${i18n.t('clipboard.add-files')}" - ?disabled="${this.buttonsDisabled}"> - <dbp-icon class="nav-icon" name="clipboard"></dbp-icon> ${i18n.t('clipboard.add-files-btn')} - </button> - <button id="clipboard-remove-files-button" @click="${() => { this.clearClipboard(); }}" - class="button" title="${(this.numberOfSelectedFiles > 0) ? i18n.t('clipboard.remove-count', {count: this.numberOfSelectedFiles}) : i18n.t('clipboard.remove-all')}" - ?disabled="${buttonsAreDisabled}"> - ${(this.numberOfSelectedFiles > 0) ? i18n.t('clipboard.remove-count-btn', {count: this.numberOfSelectedFiles}) : i18n.t('clipboard.remove-all-btn')} - </button> - </div> - <div class="btn-flex-container-mobile"> - <button id="clipboard-save-files-button" @click="${() => { this.openFileSink(); }}" - ?disabled="${buttonsAreDisabled}" - class="button" title="${(this.numberOfSelectedFiles > 0) ? i18n.t('clipboard.save-count', {count: this.numberOfSelectedFiles}) : i18n.t('clipboard.save-all')}"> - ${(this.numberOfSelectedFiles > 0) ? i18n.t('clipboard.save-count-btn', {count: this.numberOfSelectedFiles}) : i18n.t('clipboard.save-all-btn')} - </button> - </div> - - </div> - <dbp-file-source - id="file-source-clipboard" - context="${i18n.t('clipboard.add-files')}" - allowed-mime-types="${this.allowedMimeTypes}" - nextcloud-auth-url="${this.nextcloudWebAppPasswordURL}" - nextcloud-web-dav-url="${this.nextcloudWebDavURL}" - nextcloud-name="${this.nextcloudName}" - nextcloud-file-url="${this.nextcloudFileURL}" - nexcloud-auth-info="${this.nextcloudAuthInfo}" - ?nextcloud-store-session="${this.nextcloudStoreSession}" - enabled-targets="${this.allowNesting ? this.enabledTargets : this.enabledTargets.replace('clipboard', '')}" - decompress-zip - lang="${this.lang}" - text="${i18n.t('clipboard.upload-area-text')}" - button-label="${i18n.t('clipboard.upload-button-label')}" - @dbp-file-source-file-selected="${this.saveFilesToClipboardEvent}" - @dbp-nextcloud-file-picker-number-files="${this.finishedSaveFilesToClipboard}" - @dbp-file-source-file-upload-finished="${this.finishedSaveFilesToClipboard}" - ></dbp-file-source> - <dbp-file-sink id="file-sink-clipboard" - context="${(this.numberOfSelectedFiles > 0) ? i18n.t('clipboard.save-count', {count: this.numberOfSelectedFiles}) : i18n.t('clipboard.save-all')}" - filename="clipboard-documents.zip" - allowed-mime-types="${this.allowedMimeTypes}" - enabled-targets="${this.allowNesting ? this.enabledTargets : this.enabledTargets.replace('clipboard', '')}" - nextcloud-auth-url="${this.nextcloudWebAppPasswordURL}" - nextcloud-web-dav-url="${this.nextcloudWebDavURL}" - nextcloud-name="${this.nextcloudName}" - nextcloud-file-url="${this.nextcloudFileURL}" - nexcloud-auth-info="${this.nextcloudAuthInfo}" - ?nextcloud-store-session="${this.nextcloudStoreSession}" - lang="${this.lang}" - ></dbp-file-sink> + <div class="btn-flex-container-mobile"> + <button + id="clipboard-add-files-button" + @click="${() => { + this.openFileSource(); + }}" + class="button ${classMap({ + hidden: this.mode === MODE_FILE_SINK || this.mode === MODE_FILE_SOURCE, + })}" + title="${i18n.t('clipboard.add-files')}" + ?disabled="${this.buttonsDisabled}"> + <dbp-icon class="nav-icon" name="clipboard"></dbp-icon> + ${i18n.t('clipboard.add-files-btn')} + </button> + <button + id="clipboard-remove-files-button" + @click="${() => { + this.clearClipboard(); + }}" + class="button" + title="${this.numberOfSelectedFiles > 0 + ? i18n.t('clipboard.remove-count', {count: this.numberOfSelectedFiles}) + : i18n.t('clipboard.remove-all')}" + ?disabled="${buttonsAreDisabled}"> + ${this.numberOfSelectedFiles > 0 + ? i18n.t('clipboard.remove-count-btn', { + count: this.numberOfSelectedFiles, + }) + : i18n.t('clipboard.remove-all-btn')} + </button> + </div> + <div class="btn-flex-container-mobile"> + <button + id="clipboard-save-files-button" + @click="${() => { + this.openFileSink(); + }}" + ?disabled="${buttonsAreDisabled}" + class="button" + title="${this.numberOfSelectedFiles > 0 + ? i18n.t('clipboard.save-count', {count: this.numberOfSelectedFiles}) + : i18n.t('clipboard.save-all')}"> + ${this.numberOfSelectedFiles > 0 + ? i18n.t('clipboard.save-count-btn', { + count: this.numberOfSelectedFiles, + }) + : i18n.t('clipboard.save-all-btn')} + </button> + </div> + </div> + <dbp-file-source + id="file-source-clipboard" + context="${i18n.t('clipboard.add-files')}" + allowed-mime-types="${this.allowedMimeTypes}" + nextcloud-auth-url="${this.nextcloudWebAppPasswordURL}" + nextcloud-web-dav-url="${this.nextcloudWebDavURL}" + nextcloud-name="${this.nextcloudName}" + nextcloud-file-url="${this.nextcloudFileURL}" + nexcloud-auth-info="${this.nextcloudAuthInfo}" + ?nextcloud-store-session="${this.nextcloudStoreSession}" + enabled-targets="${this.allowNesting + ? this.enabledTargets + : this.enabledTargets.replace('clipboard', '')}" + decompress-zip + lang="${this.lang}" + text="${i18n.t('clipboard.upload-area-text')}" + button-label="${i18n.t('clipboard.upload-button-label')}" + @dbp-file-source-file-selected="${this.saveFilesToClipboardEvent}" + @dbp-nextcloud-file-picker-number-files="${this.finishedSaveFilesToClipboard}" + @dbp-file-source-file-upload-finished="${this + .finishedSaveFilesToClipboard}"></dbp-file-source> + <dbp-file-sink + id="file-sink-clipboard" + context="${this.numberOfSelectedFiles > 0 + ? i18n.t('clipboard.save-count', {count: this.numberOfSelectedFiles}) + : i18n.t('clipboard.save-all')}" + filename="clipboard-documents.zip" + allowed-mime-types="${this.allowedMimeTypes}" + enabled-targets="${this.allowNesting + ? this.enabledTargets + : this.enabledTargets.replace('clipboard', '')}" + nextcloud-auth-url="${this.nextcloudWebAppPasswordURL}" + nextcloud-web-dav-url="${this.nextcloudWebDavURL}" + nextcloud-name="${this.nextcloudName}" + nextcloud-file-url="${this.nextcloudFileURL}" + nexcloud-auth-info="${this.nextcloudAuthInfo}" + ?nextcloud-store-session="${this.nextcloudStoreSession}" + lang="${this.lang}"></dbp-file-sink> `; } @@ -656,7 +737,10 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { */ getClipboardSink() { const i18n = this._i18n; - const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css'); + const tabulatorCss = commonUtils.getAssetURL( + pkgName, + 'tabulator-tables/css/tabulator.min.css' + ); return html` <div class="wrapper"> <div class="content"> @@ -667,20 +751,25 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { </div> <div> ${this.getAdditionalButtons()} - <link rel="stylesheet" href="${tabulatorCss}"> + <link rel="stylesheet" href="${tabulatorCss}" /> <div class="table-wrapper"> <table id="clipboard-content-table" class="force-no-select"></table> </div> </div> </div> <div class="clipboard-footer"> - <button class="button select-button is-primary" title="${i18n.t('clipboard.sink-btn', {count: this.filesToSave.length})}" - @click="${() => {this.saveFilesToClipboard();}}"> <dbp-icon class="nav-icon" name="clipboard"></dbp-icon> ${i18n.t('clipboard.sink-btn', {count: this.filesToSave.length})} + <button + class="button select-button is-primary" + title="${i18n.t('clipboard.sink-btn', {count: this.filesToSave.length})}" + @click="${() => { + this.saveFilesToClipboard(); + }}"> + <dbp-icon class="nav-icon" name="clipboard"></dbp-icon> + ${i18n.t('clipboard.sink-btn', {count: this.filesToSave.length})} </button> </div> </div> `; - } /** @@ -689,7 +778,10 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * @returns {html} */ getClipboardSource() { - const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css'); + const tabulatorCss = commonUtils.getAssetURL( + pkgName, + 'tabulator-tables/css/tabulator.min.css' + ); const i18n = this._i18n; return html` <div class="wrapper"> @@ -701,15 +793,26 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { </div> <div> ${this.getAdditionalButtons()} - <link rel="stylesheet" href="${tabulatorCss}"> + <link rel="stylesheet" href="${tabulatorCss}" /> <div class="table-wrapper"> <table id="clipboard-content-table" class="force-no-select"></table> </div> </div> </div> <div class="clipboard-footer"> - <button class="button select-button is-primary" ?disabled="${this.clipboardSelectBtnDisabled}" - @click="${() => {this.sendClipboardFiles(this.tabulatorTable.getSelectedData());}}"> ${this.tabulatorTable && this.tabulatorTable.getSelectedRows().length > 0 ? i18n.t('clipboard.source-btn', {count: this.tabulatorTable ? this.tabulatorTable.getSelectedRows().length : 0}) : i18n.t('clipboard.source-btn-none')} + <button + class="button select-button is-primary" + ?disabled="${this.clipboardSelectBtnDisabled}" + @click="${() => { + this.sendClipboardFiles(this.tabulatorTable.getSelectedData()); + }}"> + ${this.tabulatorTable && this.tabulatorTable.getSelectedRows().length > 0 + ? i18n.t('clipboard.source-btn', { + count: this.tabulatorTable + ? this.tabulatorTable.getSelectedRows().length + : 0, + }) + : i18n.t('clipboard.source-btn-none')} </button> </div> </div> @@ -742,69 +845,69 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { margin-bottom: 0px; } - .subheadline{ + .subheadline { font-style: italic; padding-left: 2em; margin-top: -1px; margin-bottom: 1.2em; } - - .warning-container{ + + .warning-container { display: flex; flex-direction: inherit; align-items: center; } - - .warning-icon{ + + .warning-icon { margin-right: 10px; font-size: 1.5rem; margin-top: -23px; } - - .container{ + + .container { margin-top: 2rem; } - - .flex-container{ + + .flex-container { margin-bottom: 5px; } - - .select-btn-wrapper{ + + .select-btn-wrapper { float: right; } - - .init{ + + .init { margin: 0px; } - - .flex-container{ + + .flex-container { display: flex; justify-content: space-between; } - .tabulator .tabulator-tableHolder .tabulator-placeholder span{ + .tabulator .tabulator-tableHolder .tabulator-placeholder span { margin: initial; } - - .checkmark{ + + .checkmark { height: 20px; - width:20px; + width: 20px; left: 11px; top: 4px; } - - .button-container .checkmark::after{ + + .button-container .checkmark::after { left: 8px; top: 3px; width: 4px; height: 11px; } - - .table-wrapper{ + + .table-wrapper { position: relative; } - - .select-all-icon{ + + .select-all-icon { height: 30px; } @@ -816,8 +919,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { align-items: end; flex-direction: column; } - - .wrapper{ + + .wrapper { width: 100%; height: 100%; display: flex; @@ -825,107 +928,101 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { justify-content: center; /* position: relative; */ } - - .content{ + + .content { width: 100%; height: 100%; overflow-y: auto; -webkit-overflow-scrolling: touch; } - - .additional-button-container{ + + .additional-button-container { margin-top: 0.5rem; } - - .warning-container p{ + + .warning-container p { margin-top: 0px; } - - - @media only screen - and (orientation: portrait) - and (max-width: 768px) { - .flex-container{ + @media only screen and (orientation: portrait) and (max-width: 768px) { + .flex-container { justify-content: space-between; display: flex; } - - .btn-flex-container-mobile{ + + .btn-flex-container-mobile { width: 100%; display: flex; justify-content: space-between; margin-bottom: 5px; } - - .select-btn-wrapper{ + + .select-btn-wrapper { width: 100%; display: flex; justify-content: end; float: none; } - - .flex-container{ + + .flex-container { display: block; } - .checkmark{ + .checkmark { height: 25px; - width:25px; + width: 25px; left: 9px; top: 2px; } - .button-container .checkmark::after{ + .button-container .checkmark::after { left: 8px; top: 2px; width: 8px; height: 15px; } - .select-all-icon{ + .select-all-icon { height: 32px; } - - .btn-flex-container-mobile{ + + .btn-flex-container-mobile { flex-direction: column; } - - .btn-flex-container-mobile button:nth-child(2){ + + .btn-flex-container-mobile button:nth-child(2) { margin-top: 5px; } - - .warning-icon{ + + .warning-icon { margin-right: 10px; font-size: 85px; margin-top: -43px; } - } - `; } render() { - const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css'); + const tabulatorCss = commonUtils.getAssetURL( + pkgName, + 'tabulator-tables/css/tabulator.min.css' + ); if (this.mode === MODE_FILE_SINK) { return this.getClipboardSink(); - } - else if (this.mode === MODE_FILE_SOURCE) { + } else if (this.mode === MODE_FILE_SOURCE) { return this.getClipboardSource(); } else { return html` <div> - ${this.getAdditionalButtons()} - <link rel="stylesheet" href="${tabulatorCss}"> + <link rel="stylesheet" href="${tabulatorCss}" /> <div class="table-wrapper"> <table id="clipboard-content-table" class="force-no-select"></table> </div> </div> - ` ; + `; } - } -} \ No newline at end of file +} diff --git a/packages/file-handling/src/crypto.js b/packages/file-handling/src/crypto.js index 0412990e551e0e25a8bc0ed78520ad116d9c6ea3..772d25877a658bd93c8734b080042529f38fcd79 100644 --- a/packages/file-handling/src/crypto.js +++ b/packages/file-handling/src/crypto.js @@ -1,4 +1,4 @@ -import { CompactEncrypt, compactDecrypt, importJWK, base64url } from 'jose'; +import {CompactEncrypt, compactDecrypt, importJWK, base64url} from 'jose'; /** * This encrypts the payload using the token, @@ -28,7 +28,10 @@ export async function encrypt(token, payload) { */ export async function decrypt(token, payload) { const key = await importJWK({kty: 'oct', k: base64url.encode(token)}, 'PBES2-HS256+A128KW'); - const decryption = await compactDecrypt(payload, key, {alg: 'PBES2-HS256+A128KW', enc: 'A256GCM'}); + const decryption = await compactDecrypt(payload, key, { + alg: 'PBES2-HS256+A128KW', + enc: 'A256GCM', + }); const secret = new TextDecoder().decode(decryption.plaintext); return secret; @@ -40,14 +43,18 @@ export async function decrypt(token, payload) { * @param {string} token * @returns {string} */ -export function parseJwt (token) { - if (!token) - return null; +export function parseJwt(token) { + if (!token) return null; let base64Url = token.split('.')[1]; let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); - let jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }).join('')); + let jsonPayload = decodeURIComponent( + atob(base64) + .split('') + .map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join('') + ); return JSON.parse(jsonPayload); } diff --git a/packages/file-handling/src/dbp-clipboard.js b/packages/file-handling/src/dbp-clipboard.js index cc8fc3820f3c9a2d38d76ce52de4350da4c1ddeb..0812030060993bf70aa09473489526d6386d8481 100644 --- a/packages/file-handling/src/dbp-clipboard.js +++ b/packages/file-handling/src/dbp-clipboard.js @@ -1,4 +1,4 @@ -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {Clipboard} from './clipboard'; commonUtils.defineCustomElement('dbp-clipboard', Clipboard); diff --git a/packages/file-handling/src/dbp-file-handling-lit-element.js b/packages/file-handling/src/dbp-file-handling-lit-element.js index 5da4f58da8cdfc2f7a17bd71b814a374df11d156..3776598006e41d666e153ab9399683eb0eb582f1 100644 --- a/packages/file-handling/src/dbp-file-handling-lit-element.js +++ b/packages/file-handling/src/dbp-file-handling-lit-element.js @@ -1,10 +1,9 @@ import {ScopedElementsMixin} from '@open-wc/scoped-elements'; -import DBPLitElement from "../../common/dbp-lit-element"; +import DBPLitElement from '../../common/dbp-lit-element'; export default class DbpFileHandlingLitElement extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - } static get properties() { @@ -20,23 +19,22 @@ export default class DbpFileHandlingLitElement extends ScopedElementsMixin(DBPLi * @param e */ handleScroll(e) { - if (!this._(".right-paddle") || !this._(".left-paddle")) - return; + if (!this._('.right-paddle') || !this._('.left-paddle')) return; let horizontal = e.currentTarget.scrollLeft; let scrollWidth = e.currentTarget.scrollWidth - e.currentTarget.clientWidth; //e.currentTarget.scrollLeftMax isn't support except firefox - if(horizontal > 0) { - this._(".left-paddle").classList.remove("hidden"); + if (horizontal > 0) { + this._('.left-paddle').classList.remove('hidden'); } if (horizontal < scrollWidth) { - this._(".right-paddle").classList.remove("hidden"); + this._('.right-paddle').classList.remove('hidden'); } if (horizontal >= scrollWidth) { - this._(".right-paddle").classList.add("hidden"); + this._('.right-paddle').classList.add('hidden'); } if (horizontal <= 0) { - this._(".left-paddle").classList.add("hidden"); + this._('.left-paddle').classList.add('hidden'); } } @@ -49,10 +47,10 @@ export default class DbpFileHandlingLitElement extends ScopedElementsMixin(DBPLi const maxwidth = element.scrollWidth - element.clientWidth; let container = element; let scrollAmount = 0; - let slideTimer = setInterval(function(){ + let slideTimer = setInterval(function () { container.scrollLeft += 10; scrollAmount += 10; - if(scrollAmount >= maxwidth){ + if (scrollAmount >= maxwidth) { window.clearInterval(slideTimer); } }, 25); @@ -67,13 +65,12 @@ export default class DbpFileHandlingLitElement extends ScopedElementsMixin(DBPLi const minwidth = 0; let container = element; let scrollAmount = element.scrollWidth - element.clientWidth; - let slideTimer = setInterval(function(){ + let slideTimer = setInterval(function () { container.scrollLeft -= 10; scrollAmount -= 10; - if(scrollAmount <= minwidth){ + if (scrollAmount <= minwidth) { window.clearInterval(slideTimer); } }, 25); } - -} \ No newline at end of file +} diff --git a/packages/file-handling/src/dbp-file-sink.js b/packages/file-handling/src/dbp-file-sink.js index 87fd6295d190fc7390ce048488eca95705854fbd..753a97c6d980b27fc23bc0fa898b3be9d4d267e0 100644 --- a/packages/file-handling/src/dbp-file-sink.js +++ b/packages/file-handling/src/dbp-file-sink.js @@ -1,4 +1,4 @@ -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {FileSink} from './file-sink'; commonUtils.defineCustomElement('dbp-file-sink', FileSink); diff --git a/packages/file-handling/src/dbp-file-source.js b/packages/file-handling/src/dbp-file-source.js index 0da7bd7e5c463710ea50843ce23a16a1b6c4f5a0..c5370afd83be067b4fa8f1484c24533471aee154 100644 --- a/packages/file-handling/src/dbp-file-source.js +++ b/packages/file-handling/src/dbp-file-source.js @@ -1,4 +1,4 @@ -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {FileSource} from './file-source'; commonUtils.defineCustomElement('dbp-file-source', FileSource); diff --git a/packages/file-handling/src/dbp-nextcloud-file-picker.js b/packages/file-handling/src/dbp-nextcloud-file-picker.js index 976131533fd03f25ebe10d28bd1ff1eae37cd4ec..4a31a7046dcdf451e12a6ff3e5b2a8958c06769e 100644 --- a/packages/file-handling/src/dbp-nextcloud-file-picker.js +++ b/packages/file-handling/src/dbp-nextcloud-file-picker.js @@ -1,4 +1,4 @@ -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {NextcloudFilePicker} from './nextcloud-file-picker'; commonUtils.defineCustomElement('dbp-nextcloud-file-picker', NextcloudFilePicker); diff --git a/packages/file-handling/src/demo.js b/packages/file-handling/src/demo.js index 31d134881a78a429f9fd545069eae5eadc2f2f4a..816e72eadc142acf92a20102e65b9f9b689c90d8 100644 --- a/packages/file-handling/src/demo.js +++ b/packages/file-handling/src/demo.js @@ -18,17 +18,17 @@ export class FileSourceDemo extends ScopedElementsMixin(LitElement) { static get scopedElements() { return { - 'dbp-file-source': FileSource, - 'dbp-file-sink': FileSink, + 'dbp-file-source': FileSource, + 'dbp-file-sink': FileSink, }; } static get properties() { return { - lang: { type: String }, - url: { type: String }, - selectedFiles: { type: Array, attribute: false }, - selectedFilesCount: { type: Number, attribute: false }, + lang: {type: String}, + url: {type: String}, + selectedFiles: {type: Array, attribute: false}, + selectedFilesCount: {type: Number, attribute: false}, }; } @@ -36,17 +36,19 @@ export class FileSourceDemo extends ScopedElementsMixin(LitElement) { super.connectedCallback(); this.updateComplete.then(() => { - this.shadowRoot.querySelectorAll('.file-source') - .forEach(element => { - // TODO: remove orphaned event listeners - element.addEventListener('dbp-file-source-file-selected', this.addLogEntry.bind(this)); - }); + this.shadowRoot.querySelectorAll('.file-source').forEach((element) => { + // TODO: remove orphaned event listeners + element.addEventListener( + 'dbp-file-source-file-selected', + this.addLogEntry.bind(this) + ); + }); }); } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -96,11 +98,11 @@ export class FileSourceDemo extends ScopedElementsMixin(LitElement) { --FUBorder: 2px solid blue; } </style> - + <section class="section"> <div class="content"> <h1 class="title">${i18n.t('demo-title')}</h1> - <!-- <p>${unsafeHTML(i18n.t('required-server', { url: this.url}))}</p> --> + <!-- <p>${unsafeHTML(i18n.t('required-server', {url: this.url}))}</p> --> </div> <div class="content"> <h2 class="subtitle">Selected files</h2> @@ -109,74 +111,105 @@ export class FileSourceDemo extends ScopedElementsMixin(LitElement) { <h2 class="subtitle">Send files via event</h2> <p>There is no restriction for a specific file type:</p> - <button @click="${() => { this._("#file-source1").setAttribute("dialog-open", ""); }}" - class="button is-primary"> + <button + @click="${() => { + this._('#file-source1').setAttribute('dialog-open', ''); + }}" + class="button is-primary"> Open dialog </button> - <dbp-file-source id="file-source1" - class="file-source" - allowed-mime-types="*/*" - subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" - lang="en" - enabled-targets="local,nextcloud"></dbp-file-source> + <dbp-file-source + id="file-source1" + class="file-source" + allowed-mime-types="*/*" + subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" + lang="en" + enabled-targets="local,nextcloud"></dbp-file-source> <p>Only images are allowed here (JPG, PNG, GIF, TIF, ...):</p> - <button @click="${() => { this._("#file-source2").setAttribute("dialog-open", ""); }}" - class="button is-primary"> + <button + @click="${() => { + this._('#file-source2').setAttribute('dialog-open', ''); + }}" + class="button is-primary"> Open dialog </button> - <dbp-file-source id="file-source2" lang="en" url="${this.url}" - class="file-source" - allowed-mime-types="image/*" - subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" - enabled-targets="local,nextcloud" - text="Please select images"></dbp-file-source> + <dbp-file-source + id="file-source2" + lang="en" + url="${this.url}" + class="file-source" + allowed-mime-types="image/*" + subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" + enabled-targets="local,nextcloud" + text="Please select images"></dbp-file-source> <p>This is for PDF only:</p> - <button @click="${() => { this._("#file-source3").setAttribute("dialog-open", ""); }}" - class="button is-primary"> + <button + @click="${() => { + this._('#file-source3').setAttribute('dialog-open', ''); + }}" + class="button is-primary"> Open dialog </button> - <dbp-file-source id="file-source3" lang="en" url="${this.url}" - class="file-source" - allowed-mime-types="application/pdf" - subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" - enabled-targets="local,nextcloud" - text="Submit only PDF files" button-label="PDF auswählen"></dbp-file-source> + <dbp-file-source + id="file-source3" + lang="en" + url="${this.url}" + class="file-source" + allowed-mime-types="application/pdf" + subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" + enabled-targets="local,nextcloud" + text="Submit only PDF files" + button-label="PDF auswählen"></dbp-file-source> <p>Text and images (JPG, PNG, GIF, TIF, ...) :</p> - <button @click="${() => { this._("#file-source4").setAttribute("dialog-open", ""); }}" - class="button is-primary"> + <button + @click="${() => { + this._('#file-source4').setAttribute('dialog-open', ''); + }}" + class="button is-primary"> Open dialog </button> - <dbp-file-source id="file-source4" lang="en" url="${this.url}" - class="file-source" - allowed-mime-types="text/plain,image/*" - subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" - enabled-targets="local,nextcloud" - text="Please select text or images"></dbp-file-source> + <dbp-file-source + id="file-source4" + lang="en" + url="${this.url}" + class="file-source" + allowed-mime-types="text/plain,image/*" + subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" + enabled-targets="local,nextcloud" + text="Please select text or images"></dbp-file-source> <p>PDFs also in ZIPS :</p> - <button @click="${() => { this._("#file-source5").setAttribute("dialog-open", ""); }}" - class="button is-primary"> + <button + @click="${() => { + this._('#file-source5').setAttribute('dialog-open', ''); + }}" + class="button is-primary"> Open dialog </button> - <dbp-file-source id="file-source5" lang="en" url="${this.url}" - class="file-source" - allowed-mime-types="application/pdf" - decompress-zip - subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" - enabled-targets="local,nextcloud" - text="Please select PDF(s) or ZIP(s) with PDF(s)"></dbp-file-source> + <dbp-file-source + id="file-source5" + lang="en" + url="${this.url}" + class="file-source" + allowed-mime-types="application/pdf" + decompress-zip + subscribe="nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url" + enabled-targets="local,nextcloud" + text="Please select PDF(s) or ZIP(s) with PDF(s)"></dbp-file-source> <dbp-file-sink lang="en"></dbp-file-sink> - </div> + </div> </section> `; } _(selector) { - return this.shadowRoot === null ? this.querySelector(selector) : this.shadowRoot.querySelector(selector); + return this.shadowRoot === null + ? this.querySelector(selector) + : this.shadowRoot.querySelector(selector); } } diff --git a/packages/file-handling/src/file-sink.js b/packages/file-handling/src/file-sink.js index ab3680a5be82c8b719364c10bcf652ae78117c7c..d9414d43c4579b8283e8f907a50f5d4a73954119 100644 --- a/packages/file-handling/src/file-sink.js +++ b/packages/file-handling/src/file-sink.js @@ -1,18 +1,17 @@ import {createInstance} from './i18n'; import {css, html} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {Icon, MiniSpinner} from '@dbp-toolkit/common'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import {NextcloudFilePicker} from "./nextcloud-file-picker"; +import {NextcloudFilePicker} from './nextcloud-file-picker'; import {classMap} from 'lit/directives/class-map.js'; import FileSaver from 'file-saver'; -import MicroModal from "./micromodal.es"; +import MicroModal from './micromodal.es'; import * as fileHandlingStyles from './styles'; -import { send } from '@dbp-toolkit/common/notification'; -import {Clipboard} from "@dbp-toolkit/file-handling/src/clipboard"; -import DbpFileHandlingLitElement from "./dbp-file-handling-lit-element"; - +import {send} from '@dbp-toolkit/common/notification'; +import {Clipboard} from '@dbp-toolkit/file-handling/src/clipboard'; +import DbpFileHandlingLitElement from './dbp-file-handling-lit-element'; /** * FileSink web component @@ -25,12 +24,12 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { this.lang = this._i18n.language; this.nextcloudAuthUrl = ''; this.nextcloudWebDavUrl = ''; - this.nextcloudName ='Nextcloud'; + this.nextcloudName = 'Nextcloud'; this.nextcloudPath = ''; this.nextcloudFileURL = ''; this.nextcloudStoreSession = false; this.buttonLabel = ''; - this.filename = "files.zip"; + this.filename = 'files.zip'; this.files = []; this.activeTarget = 'local'; this.isDialogOpen = false; @@ -73,20 +72,25 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { activeTarget: {type: String, attribute: 'active-target'}, firstOpen: {type: Boolean, attribute: false}, nextcloudPath: {type: String, attribute: false}, - fullsizeModal: { type: Boolean, attribute: 'fullsize-modal' }, + fullsizeModal: {type: Boolean, attribute: 'fullsize-modal'}, initialFileHandlingState: {type: Object, attribute: 'initial-file-handling-state'}, }; } - connectedCallback() { super.connectedCallback(); this.updateComplete.then(() => { - this._('nav.modal-nav').addEventListener("scroll", this.handleScroll.bind(this)); + this._('nav.modal-nav').addEventListener('scroll', this.handleScroll.bind(this)); - this._('.right-paddle').addEventListener("click", this.handleScrollRight.bind(this, this._('nav.modal-nav'))); + this._('.right-paddle').addEventListener( + 'click', + this.handleScrollRight.bind(this, this._('nav.modal-nav')) + ); - this._('.left-paddle').addEventListener("click", this.handleScrollLeft.bind(this, this._('nav.modal-nav'))); + this._('.left-paddle').addEventListener( + 'click', + this.handleScrollLeft.bind(this, this._('nav.modal-nav')) + ); }); } @@ -109,7 +113,11 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { // add pseudo-random string on duplicate file name if (fileNames.indexOf(fileName) !== -1) { - fileName = commonUtils.getBaseName(fileName) + "-" + Math.random().toString(36).substring(7) + "." + + fileName = + commonUtils.getBaseName(fileName) + + '-' + + Math.random().toString(36).substring(7) + + '.' + commonUtils.getFileExtension(fileName); } @@ -117,10 +125,10 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { zip.file(fileName, file); }); - let content = await zip.generateAsync({type:"blob"}); + let content = await zip.generateAsync({type: 'blob'}); // see: https://github.com/eligrey/FileSaver.js#readme - FileSaver.saveAs(content, this.filename || "files.zip"); + FileSaver.saveAs(content, this.filename || 'files.zip'); this.closeDialog(); } @@ -128,26 +136,26 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); break; - case "enabledTargets": + case 'enabledTargets': if (!this.hasEnabledDestination(this.activeTargets)) { - this.activeTargets = this.enabledTargets.split(",")[0]; + this.activeTargets = this.enabledTargets.split(',')[0]; } break; - case "files": + case 'files': if (this.files.length !== 0) { this.openDialog(); - if (this.enabledTargets.includes("clipboard")) { - const clipboardSink = this._("#clipboard-file-picker"); + if (this.enabledTargets.includes('clipboard')) { + const clipboardSink = this._('#clipboard-file-picker'); if (clipboardSink) { - this._("#clipboard-file-picker").filesToSave = [...this.files]; + this._('#clipboard-file-picker').filesToSave = [...this.files]; } } } break; - case "initialFileHandlingState": + case 'initialFileHandlingState': //check if default destination is set if (this.firstOpen) { this.nextcloudPath = this.initialFileHandlingState.path; @@ -175,10 +183,13 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { MicroModal.close(this._('#modal-picker')); if (event.detail > 0) { send({ - "summary": i18n.t('file-sink.upload-success-title'), - "body": i18n.t('file-sink.upload-success-body', {name: this.nextcloudName, count: event.detail}), - "type": "success", - "timeout": 5, + summary: i18n.t('file-sink.upload-success-title'), + body: i18n.t('file-sink.upload-success-body', { + name: this.nextcloudName, + count: event.detail, + }), + type: 'success', + timeout: 5, }); } } @@ -186,27 +197,26 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { sendDestination() { let data = {}; if (this.activeTarget === 'nextcloud') { - data = {"target": this.activeTarget, "path": this._("#nextcloud-file-picker").directoryPath}; - + data = { + target: this.activeTarget, + path: this._('#nextcloud-file-picker').directoryPath, + }; } else { - data = {"target": this.activeTarget}; + data = {target: this.activeTarget}; } this.sendSetPropertyEvent('initial-file-handling-state', data); - } - - preventDefaults (e) { + preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } loadWebdavDirectory() { - const filePicker = this._('#nextcloud-file-picker'); if (filePicker) { - filePicker.checkLocalStorage().then(contents => { + filePicker.checkLocalStorage().then((contents) => { if (filePicker.webDavClient !== null) { filePicker.loadDirectory(filePicker.directoryPath); } @@ -219,20 +229,26 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { this.loadWebdavDirectory(); } if (this.enabledTargets.includes('clipboard')) { - if (this._('#clipboard-file-picker')._("#select_all")) { - this._('#clipboard-file-picker')._("#select_all").checked = false; + if (this._('#clipboard-file-picker')._('#select_all')) { + this._('#clipboard-file-picker')._('#select_all').checked = false; } } const filePicker = this._('#modal-picker'); if (filePicker) { MicroModal.show(filePicker, { disableScroll: true, - onClose: modal => { this.isDialogOpen = false; }, + onClose: (modal) => { + this.isDialogOpen = false; + }, }); } //check if default destination is set - if (this.initialFileHandlingState.target !== '' && typeof this.initialFileHandlingState.target !== 'undefined' && this.firstOpen) { + if ( + this.initialFileHandlingState.target !== '' && + typeof this.initialFileHandlingState.target !== 'undefined' && + this.firstOpen + ) { this.activeTarget = this.initialFileHandlingState.target; this.nextcloudPath = this.initialFileHandlingState.path; @@ -255,7 +271,7 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { filePicker.tabulatorTable.deselectRow(); filePicker.numberOfSelectedFiles = 0; if (filePicker._('#select_all')) { - filePicker._("#select_all").checked = false; + filePicker._('#select_all').checked = false; } } } @@ -266,60 +282,64 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { getClipboardHtml() { if (this.enabledTargets.includes('clipboard')) { return html` - <dbp-clipboard - id="clipboard-file-picker" - subscribe="clipboard-files:clipboard-files" - show-additional-buttons - mode="file-sink" - lang="${this.lang}" - auth-url="${this.nextcloudAuthUrl}" - enabled-targets="${this.enabledTargets}" - nextcloud-auth-url="${this.nextcloudAuthUrl}" - nextcloud-web-dav-url="${this.nextcloudWebDavUrl}" - nextcloud-name="${this.nextcloudName}" - nextcloud-file-url="${this.nextcloudFileURL}" - @dbp-clipboard-file-picker-file-uploaded="${(event) => { - this.closeDialog(event);}}"> - </dbp-clipboard>`; + <dbp-clipboard + id="clipboard-file-picker" + subscribe="clipboard-files:clipboard-files" + show-additional-buttons + mode="file-sink" + lang="${this.lang}" + auth-url="${this.nextcloudAuthUrl}" + enabled-targets="${this.enabledTargets}" + nextcloud-auth-url="${this.nextcloudAuthUrl}" + nextcloud-web-dav-url="${this.nextcloudWebDavUrl}" + nextcloud-name="${this.nextcloudName}" + nextcloud-file-url="${this.nextcloudFileURL}" + @dbp-clipboard-file-picker-file-uploaded="${(event) => { + this.closeDialog(event); + }}"></dbp-clipboard> + `; } return html``; } getNextcloudHtml() { const i18n = this._i18n; - if (this.enabledTargets.includes('nextcloud') && this.nextcloudWebDavUrl !== "" && this.nextcloudAuthUrl !== "") { + if ( + this.enabledTargets.includes('nextcloud') && + this.nextcloudWebDavUrl !== '' && + this.nextcloudAuthUrl !== '' + ) { return html` - <dbp-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}" - subscribe="html-overrides,auth" - auth-url="${this.nextcloudAuthUrl}" - web-dav-url="${this.nextcloudWebDavUrl}" - nextcloud-name="${this.nextcloudName}" - auth-info="${this.nextcloudAuthInfo}" - directory-path="${this.nextcloudPath}" - nextcloud-file-url="${this.nextcloudFileURL}" - ?store-nextcloud-session="${this.nextcloudStoreSession}" - @dbp-nextcloud-file-picker-file-uploaded="${(event) => { - this.uploadToNextcloud(event.detail); - }}" - @dbp-nextcloud-file-picker-file-uploaded-finished="${(event) => { - this.finishedFileUpload(event); - }}"> - </dbp-nextcloud-file-picker>`; + <dbp-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}" + subscribe="html-overrides,auth" + auth-url="${this.nextcloudAuthUrl}" + web-dav-url="${this.nextcloudWebDavUrl}" + nextcloud-name="${this.nextcloudName}" + auth-info="${this.nextcloudAuthInfo}" + directory-path="${this.nextcloudPath}" + nextcloud-file-url="${this.nextcloudFileURL}" + ?store-nextcloud-session="${this.nextcloudStoreSession}" + @dbp-nextcloud-file-picker-file-uploaded="${(event) => { + this.uploadToNextcloud(event.detail); + }}" + @dbp-nextcloud-file-picker-file-uploaded-finished="${(event) => { + this.finishedFileUpload(event); + }}"></dbp-nextcloud-file-picker> + `; } return html``; } - - static get styles() { - - // language=css return css` ${commonStyles.getThemeCSS()} @@ -328,11 +348,11 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { ${commonStyles.getModalDialogCSS()} ${fileHandlingStyles.getFileHandlingCss()} - .modal-container-full-size{ + .modal-container-full-size { min-width: 100%; min-height: 100%; } - + #zip-download-block { height: 100%; width: 100%; @@ -345,8 +365,8 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { .block { margin-bottom: 10px; } - - #clipboard-file-sink{ + + #clipboard-file-sink { width: 100%; height: 100%; } @@ -362,47 +382,41 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { .paddle::before { background-color: var(--dbp-base); opacity: 0.8; - content: ""; + content: ''; width: 100%; height: 100%; position: absolute; left: 0; } - .right-paddle{ + .right-paddle { right: 0px; } - .left-paddle{ + .left-paddle { left: 0px; } - .nav-wrapper{ + .nav-wrapper { position: relative; display: block; overflow-x: auto; - border:none; + border: none; } - .paddles{ + .paddles { display: none; } - .modal-nav{ + .modal-nav { height: 100%; } - @media only screen - and (orientation: portrait) - and (max-width: 768px) { - - .paddles{ + @media only screen and (orientation: portrait) and (max-width: 768px) { + .paddles { display: inherit; } - } - - `; } @@ -411,59 +425,120 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { return html` <div class="modal micromodal-slide" id="modal-picker" aria-hidden="true"> <div class="modal-overlay" tabindex="-1"> - <div class="modal-container ${classMap({"modal-container-full-size": this.fullsizeModal})}" role="dialog" aria-modal="true" aria-labelledby="modal-picker-title"> + <div + class="modal-container ${classMap({ + 'modal-container-full-size': this.fullsizeModal, + })}" + role="dialog" + aria-modal="true" + aria-labelledby="modal-picker-title"> <div class="nav-wrapper modal-nav"> <nav class="modal-nav"> - <div title="${i18n.t('file-sink.nav-local')}" - @click="${() => { this.activeTarget = "local"; }}" - class="${classMap({"active": this.activeTarget === "local", hidden: !this.hasEnabledDestination("local")})}"> + <div + title="${i18n.t('file-sink.nav-local')}" + @click="${() => { + this.activeTarget = 'local'; + }}" + class="${classMap({ + active: this.activeTarget === 'local', + hidden: !this.hasEnabledDestination('local'), + })}"> <dbp-icon class="nav-icon" name="laptop"></dbp-icon> <p>${i18n.t('file-source.nav-local')}</p> </div> - <div title="${this.nextcloudName}" - @click="${() => { this.activeTarget = "nextcloud"; this.loadWebdavDirectory();}}" - class="${classMap({"active": this.activeTarget === "nextcloud", hidden: !this.hasEnabledDestination("nextcloud") || this.nextcloudWebDavUrl === "" || this.nextcloudAuthUrl === ""})}"> + <div + title="${this.nextcloudName}" + @click="${() => { + this.activeTarget = 'nextcloud'; + this.loadWebdavDirectory(); + }}" + class="${classMap({ + active: this.activeTarget === 'nextcloud', + hidden: + !this.hasEnabledDestination('nextcloud') || + this.nextcloudWebDavUrl === '' || + this.nextcloudAuthUrl === '', + })}"> <dbp-icon class="nav-icon" name="cloud"></dbp-icon> - <p> ${this.nextcloudName} </p> + <p>${this.nextcloudName}</p> </div> - <div title="${i18n.t('file-sink.clipboard')}" - @click="${() => { this.activeTarget = "clipboard"; }}" - class="${classMap({"active": this.activeTarget === "clipboard", hidden: (!this.hasEnabledDestination("clipboard")) })}"> + <div + title="${i18n.t('file-sink.clipboard')}" + @click="${() => { + this.activeTarget = 'clipboard'; + }}" + class="${classMap({ + active: this.activeTarget === 'clipboard', + hidden: !this.hasEnabledDestination('clipboard'), + })}"> <dbp-icon class="nav-icon" name="clipboard"></dbp-icon> <p>${i18n.t('file-sink.clipboard')}</p> </div> </nav> <div class="paddles"> - <dbp-icon class="left-paddle paddle hidden" name="chevron-left" class="close-icon"></dbp-icon> - <dbp-icon class="right-paddle paddle" name="chevron-right" class="close-icon"></dbp-icon> + <dbp-icon + class="left-paddle paddle hidden" + name="chevron-left" + class="close-icon"></dbp-icon> + <dbp-icon + class="right-paddle paddle" + name="chevron-right" + class="close-icon"></dbp-icon> </div> </div> - - <div class="modal-header"> - <button title="${i18n.t('file-sink.modal-close')}" class="modal-close" aria-label="Close modal" @click="${() => { this.closeDialog();}}"> - <dbp-icon title="${i18n.t('file-sink.modal-close')}" name="close" class="close-icon"></dbp-icon> - </button> - <p class="modal-context"> ${this.context}</p> + + <div class="modal-header"> + <button + title="${i18n.t('file-sink.modal-close')}" + class="modal-close" + aria-label="Close modal" + @click="${() => { + this.closeDialog(); + }}"> + <dbp-icon + title="${i18n.t('file-sink.modal-close')}" + name="close" + class="close-icon"></dbp-icon> + </button> + <p class="modal-context">${this.context}</p> </div> - - + <main class="modal-content" id="modal-picker-content"> - <div class="source-main ${classMap({"hidden": this.activeTarget !== "local"})}"> + <div + class="source-main ${classMap({ + hidden: this.activeTarget !== 'local', + })}"> <div id="zip-download-block"> <div class="block"> - ${i18n.t('file-sink.local-intro', {'count': this.files.length})} + ${i18n.t('file-sink.local-intro', { + count: this.files.length, + })} </div> - <button class="button is-primary" - ?disabled="${this.disabled}" - @click="${() => { this.downloadCompressedFiles(); }}"> - ${i18n.t('file-sink.local-button', {'count': this.files.length})} + <button + class="button is-primary" + ?disabled="${this.disabled}" + @click="${() => { + this.downloadCompressedFiles(); + }}"> + ${i18n.t('file-sink.local-button', { + count: this.files.length, + })} </button> </div> </div> - <div class="source-main ${classMap({"hidden": this.activeTarget !== "nextcloud" || this.nextcloudWebDavUrl === "" || this.nextcloudAuthUrl === ""})}"> + <div + class="source-main ${classMap({ + hidden: + this.activeTarget !== 'nextcloud' || + this.nextcloudWebDavUrl === '' || + this.nextcloudAuthUrl === '', + })}"> ${this.getNextcloudHtml()} </div> - <div class="source-main ${classMap({"hidden": this.activeTarget !== "clipboard"})}"> + <div + class="source-main ${classMap({ + hidden: this.activeTarget !== 'clipboard', + })}"> ${this.getClipboardHtml()} </div> </main> @@ -472,4 +547,4 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { </div> `; } -} \ No newline at end of file +} diff --git a/packages/file-handling/src/file-source.js b/packages/file-handling/src/file-source.js index 95e4f7f55e1db9eb9f0658166f95d159ef9e7487..3bd9042b4fd35d59a1285178d563b7c390b05d3e 100644 --- a/packages/file-handling/src/file-source.js +++ b/packages/file-handling/src/file-source.js @@ -1,17 +1,17 @@ import {createInstance} from './i18n'; import {css, html} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {Icon, MiniSpinner} from '@dbp-toolkit/common'; -import {send} from "@dbp-toolkit/common/notification"; +import {send} from '@dbp-toolkit/common/notification'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import {NextcloudFilePicker} from "./nextcloud-file-picker"; +import {NextcloudFilePicker} from './nextcloud-file-picker'; import {classMap} from 'lit/directives/class-map.js'; import MicroModal from './micromodal.es'; import * as fileHandlingStyles from './styles'; -import {Clipboard} from "@dbp-toolkit/file-handling/src/clipboard"; -import DbpFileHandlingLitElement from "./dbp-file-handling-lit-element"; -import {humanFileSize} from "@dbp-toolkit/common/i18next"; +import {Clipboard} from '@dbp-toolkit/file-handling/src/clipboard'; +import DbpFileHandlingLitElement from './dbp-file-handling-lit-element'; +import {humanFileSize} from '@dbp-toolkit/common/i18next'; function mimeTypesToAccept(mimeTypes) { // Some operating systems can't handle mime types and @@ -30,7 +30,6 @@ function mimeTypesToAccept(mimeTypes) { return accept.join(','); } - /** * FileSource web component */ @@ -41,7 +40,7 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { this._i18n = createInstance(); this.lang = this._i18n.language; this.nextcloudAuthUrl = ''; - this.nextcloudName ='Nextcloud'; + this.nextcloudName = 'Nextcloud'; this.nextcloudWebDavUrl = ''; this.nextcloudPath = ''; this.nextcloudFileURL = ''; @@ -78,23 +77,23 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { static get properties() { return { ...super.properties, - context: { type: String, attribute: 'context'}, - lang: { type: String }, - allowedMimeTypes: { type: String, attribute: 'allowed-mime-types' }, - enabledTargets: { type: String, attribute: 'enabled-targets' }, - nextcloudAuthUrl: { type: String, attribute: 'nextcloud-auth-url' }, - nextcloudWebDavUrl: { type: String, attribute: 'nextcloud-web-dav-url' }, - nextcloudName: { type: String, attribute: 'nextcloud-name' }, - nextcloudFileURL: { type: String, attribute: 'nextcloud-file-url' }, + context: {type: String, attribute: 'context'}, + lang: {type: String}, + allowedMimeTypes: {type: String, attribute: 'allowed-mime-types'}, + enabledTargets: {type: String, attribute: 'enabled-targets'}, + nextcloudAuthUrl: {type: String, attribute: 'nextcloud-auth-url'}, + nextcloudWebDavUrl: {type: String, attribute: 'nextcloud-web-dav-url'}, + nextcloudName: {type: String, attribute: 'nextcloud-name'}, + nextcloudFileURL: {type: String, attribute: 'nextcloud-file-url'}, nextcloudAuthInfo: {type: String, attribute: 'nextcloud-auth-info'}, nextcloudStoreSession: {type: Boolean, attribute: 'nextcloud-store-session'}, - buttonLabel: { type: String, attribute: 'button-label' }, - disabled: { type: Boolean }, - decompressZip: { type: Boolean, attribute: 'decompress-zip' }, - activeTarget: { type: String, attribute: 'active-target' }, - isDialogOpen: { type: Boolean, attribute: 'dialog-open' }, - maxFileSize: { type: Number, attribute: 'max-file-size'}, - multipleFiles: { type: Number, attribute: 'number-of-files'}, + buttonLabel: {type: String, attribute: 'button-label'}, + disabled: {type: Boolean}, + decompressZip: {type: Boolean, attribute: 'decompress-zip'}, + activeTarget: {type: String, attribute: 'active-target'}, + isDialogOpen: {type: Boolean, attribute: 'dialog-open'}, + maxFileSize: {type: Number, attribute: 'max-file-size'}, + multipleFiles: {type: Number, attribute: 'number-of-files'}, initialFileHandlingState: {type: Object, attribute: 'initial-file-handling-state'}, }; @@ -103,71 +102,77 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); break; - case "enabledTargets": + case 'enabledTargets': if (!this.hasEnabledSource(this.activeTarget)) { - this.activeTarget = this.enabledTargets.split(",")[0]; + this.activeTarget = this.enabledTargets.split(',')[0]; } break; - case "isDialogOpen": + case 'isDialogOpen': if (this.isDialogOpen) { // this.setAttribute("dialog-open", ""); this.openDialog(); } else { - this.removeAttribute("dialog-open"); + this.removeAttribute('dialog-open'); // this.closeDialog(); } break; - case "initialFileHandlingState": + case 'initialFileHandlingState': //check if default destination is set if (this.firstOpen) { this.nextcloudPath = this.initialFileHandlingState.path; } break; - case "activeTarget": - if (this.activeTarget === "nextcloud") { + case 'activeTarget': + if (this.activeTarget === 'nextcloud') { this.loadWebdavDirectory(); } break; } }); super.update(changedProperties); - } connectedCallback() { super.connectedCallback(); this.updateComplete.then(() => { this.dropArea = this._('#dropArea'); - ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { + ['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => { this.dropArea.addEventListener(eventName, this.preventDefaults, false); }); - ['dragenter', 'dragover'].forEach(eventName => { + ['dragenter', 'dragover'].forEach((eventName) => { this.dropArea.addEventListener(eventName, this.highlight.bind(this), false); }); - ['dragleave', 'drop'].forEach(eventName => { + ['dragleave', 'drop'].forEach((eventName) => { this.dropArea.addEventListener(eventName, this.unhighlight.bind(this), false); }); this.dropArea.addEventListener('drop', this.handleDrop.bind(this), false); - this._('#fileElem').addEventListener('change', this.handleChange.bind(this, this._('#fileElem'))); - - this._('nav.modal-nav').addEventListener("scroll", this.handleScroll.bind(this)); - - this._('.right-paddle').addEventListener("click", this.handleScrollRight.bind(this, this._('nav.modal-nav'))); - - this._('.left-paddle').addEventListener("click", this.handleScrollLeft.bind(this, this._('nav.modal-nav'))); + this._('#fileElem').addEventListener( + 'change', + this.handleChange.bind(this, this._('#fileElem')) + ); + + this._('nav.modal-nav').addEventListener('scroll', this.handleScroll.bind(this)); + + this._('.right-paddle').addEventListener( + 'click', + this.handleScrollRight.bind(this, this._('nav.modal-nav')) + ); + + this._('.left-paddle').addEventListener( + 'click', + this.handleScrollLeft.bind(this, this._('nav.modal-nav')) + ); }); - } disconnectedCallback() { - super.disconnectedCallback(); } - preventDefaults (e) { + preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } @@ -199,14 +204,12 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { return; } - await this.handleFiles(fileElem.files); // reset the element's value so the user can upload the same file(s) again fileElem.value = ''; } - /** * Handles files that were dropped to or selected in the component * @@ -220,25 +223,29 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { let fileCount = files.length; await commonUtils.asyncArrayForEach(files, async (file, index) => { if (file.size === 0) { - console.log('file \'' + file.name + '\' has size=0 and is denied!'); + console.log("file '" + file.name + "' has size=0 and is denied!"); return; } - if(!this.checkSize(file)) { + if (!this.checkSize(file)) { return; } // check if we want to decompress the zip and queue the contained files - if (this.decompressZip - && (file.type === "application/zip" || file.type === "application/x-zip-compressed")) { + if ( + this.decompressZip && + (file.type === 'application/zip' || file.type === 'application/x-zip-compressed') + ) { // add decompressed files to tempFilesToHandle await commonUtils.asyncArrayForEach( - await this.decompressZIP(file), (file, index, array) => { + await this.decompressZIP(file), + (file, index, array) => { fileCount = index === array.length - 1 ? fileCount : fileCount + 1; - this.sendFileEvent(file,fileCount); - }); + this.sendFileEvent(file, fileCount); + } + ); return; - } else if (this.allowedMimeTypes && !this.checkFileType(file) ) { + } else if (this.allowedMimeTypes && !this.checkFileType(file)) { return; } @@ -247,7 +254,11 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { // this.dispatchEvent(new CustomEvent("dbp-file-source-selection-finished", // { "detail": {}, bubbles: true, composed: true })); - const event = new CustomEvent("dbp-file-source-file-upload-finished", { "detail": {count: fileCount}, bubbles: true, composed: true }); + const event = new CustomEvent('dbp-file-source-file-upload-finished', { + detail: {count: fileCount}, + bubbles: true, + composed: true, + }); this.dispatchEvent(event); this.closeDialog(); } @@ -259,17 +270,24 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { sendFileEvent(file, maxUpload) { this.sendSource(); MicroModal.close(this._('#modal-picker')); - const data = {"file": file, "maxUpload": maxUpload}; - const event = new CustomEvent("dbp-file-source-file-selected", { "detail": data, bubbles: true, composed: true }); + const data = {file: file, maxUpload: maxUpload}; + const event = new CustomEvent('dbp-file-source-file-selected', { + detail: data, + bubbles: true, + composed: true, + }); this.dispatchEvent(event); } sendSource() { let data = {}; if (this.activeTarget === 'nextcloud') { - data = {"target": this.activeTarget, "path": this._("#nextcloud-file-picker").directoryPath}; + data = { + target: this.activeTarget, + path: this._('#nextcloud-file-picker').directoryPath, + }; } else { - data = {"target": this.activeTarget}; + data = {target: this.activeTarget}; } this.sendSetPropertyEvent('initial-file-handling-state', data); @@ -284,16 +302,21 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { mimeTypes.forEach((str) => { const [mainType, subType] = str.split('/'); - deny = deny && ((mainType !== '*' && mainType !== fileMainType) || (subType !== '*' && subType !== fileSubType)); + deny = + deny && + ((mainType !== '*' && mainType !== fileMainType) || + (subType !== '*' && subType !== fileSubType)); }); if (deny) { - console.log(`mime type ${file.type} of file '${file.name}' is not compatible with ${this.allowedMimeTypes}`); + console.log( + `mime type ${file.type} of file '${file.name}' is not compatible with ${this.allowedMimeTypes}` + ); send({ - "summary": i18n.t('file-source.mime-type-title'), - "body": i18n.t('file-source.mime-type-body'), - "type": "danger", - "timeout": 5, + summary: i18n.t('file-source.mime-type-title'), + body: i18n.t('file-source.mime-type-body'), + type: 'danger', + timeout: 5, }); return false; } @@ -302,16 +325,18 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { checkSize(file) { const i18n = this._i18n; - if ( this.maxFileSize !== '' && (this.maxFileSize * 1000) <= file.size ) { - send({ - "summary": i18n.t('file-source.too-big-file-title'), - "body": i18n.t('file-source.too-big-file-body', {size: humanFileSize(this.maxFileSize * 1000, true)}), - "type": "danger", - "timeout": 5, - }); - return false; - } - return true; + if (this.maxFileSize !== '' && this.maxFileSize * 1000 <= file.size) { + send({ + summary: i18n.t('file-source.too-big-file-title'), + body: i18n.t('file-source.too-big-file-body', { + size: humanFileSize(this.maxFileSize * 1000, true), + }), + type: 'danger', + timeout: 5, + }); + return false; + } + return true; } hasEnabledSource(source) { @@ -330,8 +355,8 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { let filesToHandle = []; // load zip file - await JSZip.loadAsync(file) - .then(async (zip) => { + await JSZip.loadAsync(file).then( + async (zip) => { // we are not using zip.forEach because we need to handle those files synchronously which // isn't supported by JSZip (see https://github.com/Stuk/jszip/issues/281) // using zip.files directly works great! @@ -341,13 +366,13 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { return; } - await zipEntry.async("blob") - .then(async (blob) => { + await zipEntry.async('blob').then( + async (blob) => { // get mime type of Blob, see https://github.com/Stuk/jszip/issues/626 const mimeType = await commonUtils.getMimeTypeOfFile(blob); // create new file with name and mime type - const zipEntryFile = new File([blob], zipEntry.name, { type: mimeType }); + const zipEntryFile = new File([blob], zipEntry.name, {type: mimeType}); // check mime type if (!this.checkFileType(zipEntryFile)) { @@ -355,15 +380,21 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { } filesToHandle.push(zipEntryFile); - }, (e) => { + }, + (e) => { // handle the error - console.error("Decompressing of file in " + file.name + " failed: " + e.message); - }); - }); - }, function (e) { + console.error( + 'Decompressing of file in ' + file.name + ' failed: ' + e.message + ); + } + ); + }); + }, + function (e) { // handle the error - console.error("Loading of " + file.name + " failed: " + e.message); - }); + console.error('Loading of ' + file.name + ' failed: ' + e.message); + } + ); // no suitable files found if (filesToHandle.length === 0) { @@ -371,10 +402,10 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { console.error('ZIP file does not contain any files of ' + this.allowedMimeTypes); //throw new Error('ZIP file does not contain any files of ' + this.allowedMimeTypes); send({ - "summary": i18n.t('file-source.no-usable-files-in-zip'), - "body": i18n.t('file-source.no-usable-files-hint') + this.allowedMimeTypes, - "type": 'danger', - "timeout": 0, + summary: i18n.t('file-source.no-usable-files-in-zip'), + body: i18n.t('file-source.no-usable-files-hint') + this.allowedMimeTypes, + type: 'danger', + timeout: 0, }); } return filesToHandle; @@ -385,10 +416,10 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { return; } - let data = { + let data = { fileName: file.name, status: response.status, - json: {"hydra:description": ""} + json: {'hydra:description': ''}, }; try { @@ -403,7 +434,11 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { data.file = file; } - const event = new CustomEvent("dbp-file-source-file-finished", { "detail": data, bubbles: true, composed: true }); + const event = new CustomEvent('dbp-file-source-file-finished', { + detail: data, + bubbles: true, + composed: true, + }); this.dispatchEvent(event); } @@ -411,23 +446,21 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { const filePicker = this._('#nextcloud-file-picker'); // check if element is already in the dom (for example if "dialog-open" attribute is set) if (filePicker) { - filePicker.checkLocalStorage().then(contents => { + filePicker.checkLocalStorage().then((contents) => { if (filePicker.webDavClient !== null) { filePicker.loadDirectory(filePicker.directoryPath); } }); } - } openDialog() { - if (this.enabledTargets.includes('nextcloud')) { this.loadWebdavDirectory(); } - if (this.enabledTargets.includes('clipboard') && this._("#clipboard-file-picker")) { - this._("#clipboard-file-picker").generateClipboardTable(); + if (this.enabledTargets.includes('clipboard') && this._('#clipboard-file-picker')) { + this._('#clipboard-file-picker').generateClipboardTable(); } const filePicker = this._('#modal-picker'); @@ -436,20 +469,24 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { if (filePicker) { MicroModal.show(filePicker, { disableScroll: true, - onClose: modal => { + onClose: (modal) => { this.isDialogOpen = false; const filePicker = this._('#nextcloud-file-picker'); if (filePicker) { - filePicker.selectAllButton = true;} + filePicker.selectAllButton = true; } + }, }); } - //check if default source is set - if (this.initialFileHandlingState.target !== '' && typeof this.initialFileHandlingState.target !== 'undefined' && this.firstOpen) { + if ( + this.initialFileHandlingState.target !== '' && + typeof this.initialFileHandlingState.target !== 'undefined' && + this.firstOpen + ) { this.activeDestination = this.initialFileHandlingState.target; this.nextcloudPath = this.initialFileHandlingState.path; const filePicker = this._('#nextcloud-file-picker'); @@ -467,10 +504,9 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { if (this.enabledTargets.includes('nextcloud')) { const filePicker = this._('#nextcloud-file-picker'); if (filePicker && filePicker.tabulatorTable) { - filePicker.tabulatorTable.deselectRow(); if (filePicker._('#select_all')) { - filePicker._("#select_all").checked = false; + filePicker._('#select_all').checked = false; } } } @@ -481,7 +517,7 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { filePicker.numberOfSelectedFiles = 0; filePicker.tabulatorTable.deselectRow(); if (filePicker._('#select_all')) { - filePicker._("#select_all").checked = false; + filePicker._('#select_all').checked = false; } } } @@ -491,51 +527,57 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { getClipboardHtml() { if (this.enabledTargets.includes('clipboard')) { return html` - <dbp-clipboard - id="clipboard-file-picker" - mode="file-source" - subscribe="clipboard-files:clipboard-files" - lang="${this.lang}" - auth-url="${this.nextcloudAuthUrl}" - enabled-targets="${this.enabledTargets}" - nextcloud-auth-url="${this.nextcloudAuthUrl}" - nextcloud-web-dav-url="${this.nextcloudWebDavUrl}" - nextcloud-name="${this.nextcloudName}" - nextcloud-file-url="${this.nextcloudFileURL}" - allowed-mime-types="${this.allowedMimeTypes}" - @dbp-clipboard-file-picker-file-downloaded="${(event) => { - this.sendFileEvent(event.detail.file);}}"> - </dbp-clipboard>`; + <dbp-clipboard + id="clipboard-file-picker" + mode="file-source" + subscribe="clipboard-files:clipboard-files" + lang="${this.lang}" + auth-url="${this.nextcloudAuthUrl}" + enabled-targets="${this.enabledTargets}" + nextcloud-auth-url="${this.nextcloudAuthUrl}" + nextcloud-web-dav-url="${this.nextcloudWebDavUrl}" + nextcloud-name="${this.nextcloudName}" + nextcloud-file-url="${this.nextcloudFileURL}" + allowed-mime-types="${this.allowedMimeTypes}" + @dbp-clipboard-file-picker-file-downloaded="${(event) => { + this.sendFileEvent(event.detail.file); + }}"></dbp-clipboard> + `; } return html``; } getNextcloudHtml() { - if (this.enabledTargets.includes('nextcloud') && this.nextcloudWebDavUrl !== "" && this.nextcloudAuthUrl !== "") { + if ( + this.enabledTargets.includes('nextcloud') && + this.nextcloudWebDavUrl !== '' && + this.nextcloudAuthUrl !== '' + ) { return html` - <dbp-nextcloud-file-picker id="nextcloud-file-picker" - class="${classMap({hidden: this.nextcloudWebDavUrl === "" || this.nextcloudAuthUrl === ""})}" - ?disabled="${this.disabled}" - lang="${this.lang}" - subscribe="html-overrides,auth" - auth-url="${this.nextcloudAuthUrl}" - web-dav-url="${this.nextcloudWebDavUrl}" - nextcloud-name="${this.nextcloudName}" - nextcloud-file-url="${this.nextcloudFileURL}" - ?store-nextcloud-session="${this.nextcloudStoreSession}" - auth-info="${this.nextcloudAuthInfo}" - allowed-mime-types="${this.allowedMimeTypes}" - max-selected-items="${this.multipleFiles}" - @dbp-nextcloud-file-picker-file-downloaded="${(event) => { - this.sendFileEvent(event.detail.file, event.detail.maxUpload);}}"> - </dbp-nextcloud-file-picker>`; + <dbp-nextcloud-file-picker + id="nextcloud-file-picker" + class="${classMap({ + hidden: this.nextcloudWebDavUrl === '' || this.nextcloudAuthUrl === '', + })}" + ?disabled="${this.disabled}" + lang="${this.lang}" + subscribe="html-overrides,auth" + auth-url="${this.nextcloudAuthUrl}" + web-dav-url="${this.nextcloudWebDavUrl}" + nextcloud-name="${this.nextcloudName}" + nextcloud-file-url="${this.nextcloudFileURL}" + ?store-nextcloud-session="${this.nextcloudStoreSession}" + auth-info="${this.nextcloudAuthInfo}" + allowed-mime-types="${this.allowedMimeTypes}" + max-selected-items="${this.multipleFiles}" + @dbp-nextcloud-file-picker-file-downloaded="${(event) => { + this.sendFileEvent(event.detail.file, event.detail.maxUpload); + }}"></dbp-nextcloud-file-picker> + `; } return html``; } - - - static get styles() { // language=css return css` @@ -550,13 +592,17 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { p { margin-top: 0; } - + .block { margin-bottom: 10px; } - + #dropArea { - border: var(--dbp-border, var(--FUBorderWidth, 2px) var(--FUBorderStyle, dashed) var(--FUBBorderColor, black)); + border: var( + --dbp-border, + var(--FUBorderWidth, 2px) var(--FUBorderStyle, dashed) + var(--FUBBorderColor, black) + ); border-style: var(--FUBorderStyle, dashed); border-radius: var(--FUBorderRadius, var(--dbp-border-radius, 0)); border-width: var(--FUBorderWidth, 2px); @@ -571,16 +617,16 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { align-items: center; text-align: center; } - + #dropArea.highlight { border-color: var(--FUBorderColorHighlight, purple); } - - #clipboard-file-picker{ + + #clipboard-file-picker { width: 100%; height: 100%; } - + .paddle { position: absolute; top: 0px; @@ -588,57 +634,48 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { box-sizing: content-box; height: 100%; } - + .paddle::before { background-color: var(--dbp-base); opacity: 0.8; - content: ""; + content: ''; width: 100%; height: 100%; position: absolute; left: 0; } - - .right-paddle{ + + .right-paddle { right: 0px; } - .left-paddle{ + .left-paddle { left: 0px; } - - .nav-wrapper{ + + .nav-wrapper { position: relative; display: block; overflow-x: auto; - border:none; + border: none; } - - .paddles{ + + .paddles { display: none; } - - .modal-nav{ + + .modal-nav { height: 100%; } - - - @media only screen - and (orientation: portrait) - and (max-width: 768px) { - #dropArea{ + @media only screen and (orientation: portrait) and (max-width: 768px) { + #dropArea { height: 100%; } - - } - @media only screen - and (orientation: portrait) - and (max-width: 340px) { - - .paddles{ + @media only screen and (orientation: portrait) and (max-width: 340px) { + .paddles { display: inherit; } } @@ -649,94 +686,151 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { const i18n = this._i18n; let allowedMimeTypes = this.allowedMimeTypes; - if (this.decompressZip && this.allowedMimeTypes !== "") { - allowedMimeTypes += ",application/zip,application/x-zip-compressed"; + if (this.decompressZip && this.allowedMimeTypes !== '') { + allowedMimeTypes += ',application/zip,application/x-zip-compressed'; } let inputFile = html``; - if (this.multipleFiles > 1 || this.multipleFiles === true ) { - inputFile = html `<input ?disabled="${this.disabled}" - type="file" - id="fileElem" - multiple - accept="${mimeTypesToAccept(allowedMimeTypes)}" - name='file'>`; + if (this.multipleFiles > 1 || this.multipleFiles === true) { + inputFile = html` + <input + ?disabled="${this.disabled}" + type="file" + id="fileElem" + multiple + accept="${mimeTypesToAccept(allowedMimeTypes)}" + name="file" /> + `; } else { - inputFile = html `<input ?disabled="${this.disabled}" - type="file" - id="fileElem" - accept="${mimeTypesToAccept(allowedMimeTypes)}" - name='file'>`; + inputFile = html` + <input + ?disabled="${this.disabled}" + type="file" + id="fileElem" + accept="${mimeTypesToAccept(allowedMimeTypes)}" + name="file" /> + `; } return html` -<!-- + <!-- <button class="button" ?disabled="${this.disabled}" - @click="${() => { this.openDialog(); }}">${i18n.t('file-source.open-menu')}</button> + @click="${() => { + this.openDialog(); + }}">${i18n.t('file-source.open-menu')}</button> --> <div class="modal micromodal-slide" id="modal-picker" aria-hidden="true"> <div class="modal-overlay" tabindex="-1" data-micromodal-close> - <div class="modal-container" role="dialog" aria-modal="true" aria-labelledby="modal-picker-title"> + <div + class="modal-container" + role="dialog" + aria-modal="true" + aria-labelledby="modal-picker-title"> <div class="nav-wrapper modal-nav"> <nav class="modal-nav"> - <div title="${i18n.t('file-source.nav-local')}" - @click="${() => { this.activeTarget = "local"; }}" - class="${classMap({"active": this.activeTarget === "local", hidden: !this.hasEnabledSource("local")})}"> + <div + title="${i18n.t('file-source.nav-local')}" + @click="${() => { + this.activeTarget = 'local'; + }}" + class="${classMap({ + active: this.activeTarget === 'local', + hidden: !this.hasEnabledSource('local'), + })}"> <dbp-icon class="nav-icon" name="laptop"></dbp-icon> <p>${i18n.t('file-source.nav-local')}</p> </div> - <div title="Nextcloud" - @click="${() => { this.activeTarget = "nextcloud";}}" - class="${classMap({"active": this.activeTarget === "nextcloud", hidden: !this.hasEnabledSource("nextcloud") || this.nextcloudWebDavUrl === "" || this.nextcloudAuthUrl === ""})}"> + <div + title="Nextcloud" + @click="${() => { + this.activeTarget = 'nextcloud'; + }}" + class="${classMap({ + active: this.activeTarget === 'nextcloud', + hidden: + !this.hasEnabledSource('nextcloud') || + this.nextcloudWebDavUrl === '' || + this.nextcloudAuthUrl === '', + })}"> <dbp-icon class="nav-icon" name="cloud"></dbp-icon> - <p> ${this.nextcloudName} </p> + <p>${this.nextcloudName}</p> </div> - <div title="${i18n.t('file-source.clipboard')}" - @click="${() => { this.activeTarget = "clipboard"; }}" - class="${classMap({"active": this.activeTarget === "clipboard", hidden: !this.hasEnabledSource("clipboard") })}"> + <div + title="${i18n.t('file-source.clipboard')}" + @click="${() => { + this.activeTarget = 'clipboard'; + }}" + class="${classMap({ + active: this.activeTarget === 'clipboard', + hidden: !this.hasEnabledSource('clipboard'), + })}"> <dbp-icon class="nav-icon" name="clipboard"></dbp-icon> <p>${i18n.t('file-source.clipboard')}</p> </div> </nav> <div class="paddles"> - <dbp-icon class="left-paddle paddle hidden" name="chevron-left" class="close-icon"></dbp-icon> - <dbp-icon class="right-paddle paddle" name="chevron-right" class="close-icon"></dbp-icon> + <dbp-icon + class="left-paddle paddle hidden" + name="chevron-left" + class="close-icon"></dbp-icon> + <dbp-icon + class="right-paddle paddle" + name="chevron-right" + class="close-icon"></dbp-icon> </div> </div> <div class="modal-header"> - <button title="${i18n.t('file-source.modal-close')}" class="modal-close" aria-label="Close modal" @click="${() => {this.closeDialog();}}"> - <dbp-icon name="close" class="close-icon"></dbp-icon> + <button + title="${i18n.t('file-source.modal-close')}" + class="modal-close" + aria-label="Close modal" + @click="${() => { + this.closeDialog(); + }}"> + <dbp-icon name="close" class="close-icon"></dbp-icon> </button> - - <p class="modal-context"> ${this.context}</p> + + <p class="modal-context">${this.context}</p> </div> <main class="modal-content" id="modal-picker-content"> - - <div class="source-main ${classMap({"hidden": this.activeTarget !== "local"})}"> + <div + class="source-main ${classMap({ + hidden: this.activeTarget !== 'local', + })}"> <div id="dropArea"> <div class="block"> <p>${i18n.t('intro')}</p> </div> - - + ${inputFile} - <label class="button is-primary" for="fileElem" ?disabled="${this.disabled}"> + <label + class="button is-primary" + for="fileElem" + ?disabled="${this.disabled}"> ${this.buttonLabel || i18n.t('upload-label')} </label> - </div> </div> - <div class="source-main ${classMap({"hidden": this.activeTarget !== "nextcloud" || this.nextcloudWebDavUrl === "" || this.nextcloudAuthUrl === ""})}"> + <div + class="source-main ${classMap({ + hidden: + this.activeTarget !== 'nextcloud' || + this.nextcloudWebDavUrl === '' || + this.nextcloudAuthUrl === '', + })}"> ${this.getNextcloudHtml()} </div> - <div class="source-main ${classMap({"hidden": (this.activeTarget !== "clipboard")})}"> + <div + class="source-main ${classMap({ + hidden: this.activeTarget !== 'clipboard', + })}"> ${this.getClipboardHtml()} </div> </main> </div> </div> </div> - `; + `; } -} \ No newline at end of file +} diff --git a/packages/file-handling/src/i18n.js b/packages/file-handling/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/file-handling/src/i18n.js +++ b/packages/file-handling/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _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 index 52b6bd660e6de9e2442d4f2d7bf0ab56e89e741b..9fb3f2a2d4a30e36e8ccae808b6c912e86720d04 100644 --- a/packages/file-handling/src/i18n/de/translation.json +++ b/packages/file-handling/src/i18n/de/translation.json @@ -1,137 +1,137 @@ { - "demo-title": "Datei Abgabe Demo", - "intro": "Sie können in diesem Bereich Dateien per Drag & Drop oder per Direktauswahl hochladen. Die Dateien dürfen sich auch in ZIP-Archiven befinden.", - "upload-label": "Dateiauswahl", - "file-source": { - "modal-close": "Dialog schließen", - "nav-local": "Lokaler Computer", - "no-usable-files-in-zip": "ZIP Datei enthält keine verwendbaren Dateien", - "no-usable-files-hint": "Laden Sie eine ZIP Datei mit Dateien von folgendem Typ hoch: ", - "clipboard": "Zwischenablage", - "mime-type-title": "Nicht unterstützes Dateiformat", - "mime-type-body": "Das Dateiformat wird von dieser Applikation nicht unterstützt.", - "too-big-file-title": "Datei ist zu groß!", - "too-big-file-body": "Die Datei darf maximal {{size}} haben.", - "open-menu": "" - }, - "file-sink": { - "local-intro": "{{count}} Datei herunterladen", - "local-button": "Datei herunterladen", - "modal-close": "Dialog schließen", - "nav-local": "Lokaler Computer", - "upload-success-title": "Erfolgreich hochgeladen", - "upload-success-body": "Sie haben {{count}} Datei erfolgreich in {{name}} hochgeladen.", - "upload-success-body_plural": "Sie haben {{count}} Dateien erfolgreich in {{name}} hochgeladen.", - "clipboard": "Zwischenablage", - "select-directory": "" - }, - "nextcloud-file-picker": { - "open-nextcloud-file-picker": "Dateien von {{name}} wählen", - "folder-home": "In das Home Verzeichnis springen", - "select-files": "Dateien auswählen", - "select-files-btn": "Datei auswählen", - "select-files-btn_plural": "{{count}} Dateien auswählen", - "refresh-nextcloud-file-picker": "Erneut verbinden", - "loadpath-nextcloud-file-picker": "Das {{name}} 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", - "init-text-1": "Wählen Sie Ihre Dateien von {{name}}.", - "init-text-2": "Sie müssen sich zuerst authentifizieren.", - "auth-info": "Eine neue Seite wird geöffnet, um Ihr Konto zu verbinden.", - "connect-nextcloud": "{{name}} verbinden", - "no-data": "In diesem Ordner befinden sich keine Dateien.", - "no-data-type": "In diesem Ordner befinden sich keine Daten vom benötigten Typ.", - "no-favorites": "Es wurden keine Favoriten des entsprechenden Typs gefunden. Definieren Sie Dateien und Ordner in Ihrer {{name}} als Favoriten, um diese hier anzuzeigen.", - "no-recent-files": "Es wurden keine entsprechenden Dateien und Ordner innerhalb der letzten 3 Monate gefunden.", - "webdav-error": "Etwas ist schief gelaufen: {{error}}", - "add-folder-error": "Die Ressource \"{{folder}}\", ist bereits vorhanden.", - "add-folder-error-empty": "Der Ordnername darf nicht leer sein.", - "add-folder-success": "Der Ordner \"{{folder}}\" wurde erfolgreich erstellt.", - "add-folder-open": "Neuer Ordner Dialog öffnen", - "add-folder-close": "Neuer Ordner Dialog schließen", - "add-folder": "Neuen Ordner erstellen", - "new-folder-placeholder": "Neuer Ordner", - "load-in-folder": "Ins aktuelle Verzeichnis laden", - "load-to-folder": "Im ausgewählten Ordner hochladen", - "replace-title-1": "Es ist bereits eine Datei mit dem Namen ", - "replace-title-2": " vorhanden", - "replace-text": "Was möchten Sie tun", - "replace-new_name": "Neuer Name", - "replace-replace": "Ersetzen", - "replace-skip": "Ãœberspringen", - "replace-cancel": "Abbrechen", - "replace-cancel-all": "Alle abbrechen", - "replace-mode-all": "Für alle zukünftigen Konflikte übernehmen", - "something-went-wrong": "Etwas ist schief gelaufen. Bitte verbinden Sie sich erneut.", - "upload-to": "Es wird nach {{- path}} hochgeladen ...", - "readonly": "Sie dürfen in diesem Ordner nichts hochladen.", - "onlycreate": "Sie dürfen in diesem Ordner nur neue Dateien erstellen.", - "onlyedit": "Sie dürfen in diesem Ordner nur Dateien bearbeiten.", - "abort": "Vorgang abbrechen", - "abort-message": "Vorgang wurde abgebrochen.", - "error-save-to-favorites": "Speichern in Favoriten nicht möglich! Bitte wählen Sie einen Ordner innerhalb der Favoriten aus.", - "error-save-to-recent": "Speichern in den neuesten Dateien nicht möglich! Bitte wählen Sie einen Ordner innerhalb der neuesten Dateien aus.", - "recent-files-link-text": "Neueste Dateien", - "favorites-link-text": "Meine Favoriten", - "remember-me": "Mit {{name}} verbunden bleiben", - "log-out": "Verbindung trennen", - "open-submenu": "Untermenü öffnen", - "show-only-my-files": "Nur eigene Dateien zeigen", - "favorites-title": "Favoriten", - "recent-files-title": "Neueste Dateien", - "my-recent-files-title": "Meine neuesten Dateien", - "my-recent-files-link-text": "Meine neuesten Dateien", - "all-recent-files-link-text": "Alle neuesten Dateien" - }, - "clipboard": { - "add-files": "Dateien der Zwischenablage hinzufügen", - "add-files-btn": "Dateien hinzufügen", - "remove-all": "Alle Dateien aus der Zwischenablage entfernen", - "remove-all-btn": "Dateien entfernen", - "remove-count": "Eine Datei aus der Zwischenablage entfernen", - "remove-count_plural": "{{count}} Dateien aus der Zwischenablage entfernen", - "remove-count-btn": "Datei entfernen", - "remove-count-btn_plural": "{{count}} Dateien entfernen", - "save-all": "Alle Dateien aus der Zwischenablage sichern", - "save-all-btn": "Dateien sichern", - "save-count-btn": "Datei sichern", - "save-count-btn_plural": "{{count}} Dateien sichern", - "save-count": "Eine Datei aus der Zwischenablage sichern", - "save-count_plural": "{{count}} Dateien aus der Zwischenablage sichern", - "file-name": "Name", - "file-size": "Größe", - "file-type": "Art", - "file-mod": "Geändert", - "no-data": "Aktuell befinden sich keine Dateien in der Zwischenablage.", - "saved-files-title": "Datei erfolgreich abgelegt", - "saved-files-title_plural": "Dateien erfolgreich abgelegt", - "saved-files-body": "Eine Datei wurde erfolgreich temporär in der Zwischenablage abgelegt und kann jetzt innerhalb dieser Applikation verwendet werden.", - "saved-files-body_plural": "{{count}} Dateien wurde erfolgreich temporär in der Zwischenablage abgelegt und können jetzt innerhalb dieser Applikation verwendet werden.", - "clear-clipboard-title": "Zwischenablage geleert", - "clear-clipboard-body": "Die Zwischenablage wurde erfolgreich geleert.", - "clear-count-clipboard-title": "Datei entfernt", - "clear-count-clipboard-title_plural": "Dateien entfernt", - "clear-count-clipboard-body": "Eine Datei wurde erfolgreich aus der Zwischenablage entfernt.", - "clear-count-clipboard-body_plural": "{{count}} Dateien wurde erfolgreich aus der Zwischenablage entfernt.", - "file-warning": "Achtung!", - "file-warning-body": "Es befindet sich noch eine Datei in der Zwischenablage. Die Zwischenablage wird beim Verlassen der Seite verworfen.", - "file-warning-body_plural": "Es befinden sich noch {{count}} Dateien in der Zwischenablage. Die Zwischenablage wird beim Verlassen der Seite verworfen.", - "upload-area-text": "Sie können in diesem Bereich Dokumente per Drag & Drop oder per Direktauswahl hochladen.", - "upload-button-label": "Dateien auswählen", - "warning": "Vorsicht! Wenn Sie den Browser schließen oder die Seite neu laden wird die bestehende Zwischenablage automatisch verworfen!", - "source-title": "Von der Zwischenablage auswählen", - "source-btn": "Datei auswählen", - "source-btn_plural": "{{count}} Dateien auswählen", - "source-btn-none": "Dateien auswählen", - "sink-title": "Dateien in der Zwischenablage ablegen", - "sink-btn": "{{count}} Datei ablegen", - "sink-btn_plural": "{{count}} Dateien ablegen", - "select-all": "Alle auswählen", - "select-nothing": "Nichts auswählen" - }, - "required-server": "" + "demo-title": "Datei Abgabe Demo", + "intro": "Sie können in diesem Bereich Dateien per Drag & Drop oder per Direktauswahl hochladen. Die Dateien dürfen sich auch in ZIP-Archiven befinden.", + "upload-label": "Dateiauswahl", + "file-source": { + "modal-close": "Dialog schließen", + "nav-local": "Lokaler Computer", + "no-usable-files-in-zip": "ZIP Datei enthält keine verwendbaren Dateien", + "no-usable-files-hint": "Laden Sie eine ZIP Datei mit Dateien von folgendem Typ hoch: ", + "clipboard": "Zwischenablage", + "mime-type-title": "Nicht unterstützes Dateiformat", + "mime-type-body": "Das Dateiformat wird von dieser Applikation nicht unterstützt.", + "too-big-file-title": "Datei ist zu groß!", + "too-big-file-body": "Die Datei darf maximal {{size}} haben.", + "open-menu": "" + }, + "file-sink": { + "local-intro": "{{count}} Datei herunterladen", + "local-button": "Datei herunterladen", + "modal-close": "Dialog schließen", + "nav-local": "Lokaler Computer", + "upload-success-title": "Erfolgreich hochgeladen", + "upload-success-body": "Sie haben {{count}} Datei erfolgreich in {{name}} hochgeladen.", + "upload-success-body_plural": "Sie haben {{count}} Dateien erfolgreich in {{name}} hochgeladen.", + "clipboard": "Zwischenablage", + "select-directory": "" + }, + "nextcloud-file-picker": { + "open-nextcloud-file-picker": "Dateien von {{name}} wählen", + "folder-home": "In das Home Verzeichnis springen", + "select-files": "Dateien auswählen", + "select-files-btn": "Datei auswählen", + "select-files-btn_plural": "{{count}} Dateien auswählen", + "refresh-nextcloud-file-picker": "Erneut verbinden", + "loadpath-nextcloud-file-picker": "Das {{name}} 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", + "init-text-1": "Wählen Sie Ihre Dateien von {{name}}.", + "init-text-2": "Sie müssen sich zuerst authentifizieren.", + "auth-info": "Eine neue Seite wird geöffnet, um Ihr Konto zu verbinden.", + "connect-nextcloud": "{{name}} verbinden", + "no-data": "In diesem Ordner befinden sich keine Dateien.", + "no-data-type": "In diesem Ordner befinden sich keine Daten vom benötigten Typ.", + "no-favorites": "Es wurden keine Favoriten des entsprechenden Typs gefunden. Definieren Sie Dateien und Ordner in Ihrer {{name}} als Favoriten, um diese hier anzuzeigen.", + "no-recent-files": "Es wurden keine entsprechenden Dateien und Ordner innerhalb der letzten 3 Monate gefunden.", + "webdav-error": "Etwas ist schief gelaufen: {{error}}", + "add-folder-error": "Die Ressource \"{{folder}}\", ist bereits vorhanden.", + "add-folder-error-empty": "Der Ordnername darf nicht leer sein.", + "add-folder-success": "Der Ordner \"{{folder}}\" wurde erfolgreich erstellt.", + "add-folder-open": "Neuer Ordner Dialog öffnen", + "add-folder-close": "Neuer Ordner Dialog schließen", + "add-folder": "Neuen Ordner erstellen", + "new-folder-placeholder": "Neuer Ordner", + "load-in-folder": "Ins aktuelle Verzeichnis laden", + "load-to-folder": "Im ausgewählten Ordner hochladen", + "replace-title-1": "Es ist bereits eine Datei mit dem Namen ", + "replace-title-2": " vorhanden", + "replace-text": "Was möchten Sie tun", + "replace-new_name": "Neuer Name", + "replace-replace": "Ersetzen", + "replace-skip": "Ãœberspringen", + "replace-cancel": "Abbrechen", + "replace-cancel-all": "Alle abbrechen", + "replace-mode-all": "Für alle zukünftigen Konflikte übernehmen", + "something-went-wrong": "Etwas ist schief gelaufen. Bitte verbinden Sie sich erneut.", + "upload-to": "Es wird nach {{- path}} hochgeladen ...", + "readonly": "Sie dürfen in diesem Ordner nichts hochladen.", + "onlycreate": "Sie dürfen in diesem Ordner nur neue Dateien erstellen.", + "onlyedit": "Sie dürfen in diesem Ordner nur Dateien bearbeiten.", + "abort": "Vorgang abbrechen", + "abort-message": "Vorgang wurde abgebrochen.", + "error-save-to-favorites": "Speichern in Favoriten nicht möglich! Bitte wählen Sie einen Ordner innerhalb der Favoriten aus.", + "error-save-to-recent": "Speichern in den neuesten Dateien nicht möglich! Bitte wählen Sie einen Ordner innerhalb der neuesten Dateien aus.", + "recent-files-link-text": "Neueste Dateien", + "favorites-link-text": "Meine Favoriten", + "remember-me": "Mit {{name}} verbunden bleiben", + "log-out": "Verbindung trennen", + "open-submenu": "Untermenü öffnen", + "show-only-my-files": "Nur eigene Dateien zeigen", + "favorites-title": "Favoriten", + "recent-files-title": "Neueste Dateien", + "my-recent-files-title": "Meine neuesten Dateien", + "my-recent-files-link-text": "Meine neuesten Dateien", + "all-recent-files-link-text": "Alle neuesten Dateien" + }, + "clipboard": { + "add-files": "Dateien der Zwischenablage hinzufügen", + "add-files-btn": "Dateien hinzufügen", + "remove-all": "Alle Dateien aus der Zwischenablage entfernen", + "remove-all-btn": "Dateien entfernen", + "remove-count": "Eine Datei aus der Zwischenablage entfernen", + "remove-count_plural": "{{count}} Dateien aus der Zwischenablage entfernen", + "remove-count-btn": "Datei entfernen", + "remove-count-btn_plural": "{{count}} Dateien entfernen", + "save-all": "Alle Dateien aus der Zwischenablage sichern", + "save-all-btn": "Dateien sichern", + "save-count-btn": "Datei sichern", + "save-count-btn_plural": "{{count}} Dateien sichern", + "save-count": "Eine Datei aus der Zwischenablage sichern", + "save-count_plural": "{{count}} Dateien aus der Zwischenablage sichern", + "file-name": "Name", + "file-size": "Größe", + "file-type": "Art", + "file-mod": "Geändert", + "no-data": "Aktuell befinden sich keine Dateien in der Zwischenablage.", + "saved-files-title": "Datei erfolgreich abgelegt", + "saved-files-title_plural": "Dateien erfolgreich abgelegt", + "saved-files-body": "Eine Datei wurde erfolgreich temporär in der Zwischenablage abgelegt und kann jetzt innerhalb dieser Applikation verwendet werden.", + "saved-files-body_plural": "{{count}} Dateien wurde erfolgreich temporär in der Zwischenablage abgelegt und können jetzt innerhalb dieser Applikation verwendet werden.", + "clear-clipboard-title": "Zwischenablage geleert", + "clear-clipboard-body": "Die Zwischenablage wurde erfolgreich geleert.", + "clear-count-clipboard-title": "Datei entfernt", + "clear-count-clipboard-title_plural": "Dateien entfernt", + "clear-count-clipboard-body": "Eine Datei wurde erfolgreich aus der Zwischenablage entfernt.", + "clear-count-clipboard-body_plural": "{{count}} Dateien wurde erfolgreich aus der Zwischenablage entfernt.", + "file-warning": "Achtung!", + "file-warning-body": "Es befindet sich noch eine Datei in der Zwischenablage. Die Zwischenablage wird beim Verlassen der Seite verworfen.", + "file-warning-body_plural": "Es befinden sich noch {{count}} Dateien in der Zwischenablage. Die Zwischenablage wird beim Verlassen der Seite verworfen.", + "upload-area-text": "Sie können in diesem Bereich Dokumente per Drag & Drop oder per Direktauswahl hochladen.", + "upload-button-label": "Dateien auswählen", + "warning": "Vorsicht! Wenn Sie den Browser schließen oder die Seite neu laden wird die bestehende Zwischenablage automatisch verworfen!", + "source-title": "Von der Zwischenablage auswählen", + "source-btn": "Datei auswählen", + "source-btn_plural": "{{count}} Dateien auswählen", + "source-btn-none": "Dateien auswählen", + "sink-title": "Dateien in der Zwischenablage ablegen", + "sink-btn": "{{count}} Datei ablegen", + "sink-btn_plural": "{{count}} Dateien ablegen", + "select-all": "Alle auswählen", + "select-nothing": "Nichts auswählen" + }, + "required-server": "" } diff --git a/packages/file-handling/src/i18n/en/translation.json b/packages/file-handling/src/i18n/en/translation.json index ab851556fdfa875a1788d64042d13604658133df..0187b008ba03e24e4b7de0d9a727736cd8c7a026 100644 --- a/packages/file-handling/src/i18n/en/translation.json +++ b/packages/file-handling/src/i18n/en/translation.json @@ -1,137 +1,137 @@ { - "demo-title": "File Upload Demo", - "required-server": "You need an upload server listening at <a href=\"{{- url}}\"><tt>{{- url}}</tt></a> to receive the files...", - "intro": "Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region.", - "upload-label": "Select some files", - "file-source": { - "modal-close": "Close dialog", - "nav-local": "My device", - "no-usable-files-in-zip": "ZIP file does not contain any usable files", - "no-usable-files-hint": "Upload a ZIP file with file type(s) of ", - "clipboard": "Clipboard", - "mime-type-title": "Unsupported file format", - "mime-type-body": "The file format is not supported by this application.", - "too-big-file-title": "The file is too big!", - "too-big-file-body": "The file can have a maximum of {{size}}.", - "open-menu": "" - }, - "file-sink": { - "local-intro": "Download {{count}} file", - "local-button": "Download file", - "modal-close": "Close dialog", - "nav-local": "My device", - "upload-success-title": "Successful uploaded", - "upload-success-body": "You have successfully uploaded {{count}} file to {{name}}.", - "upload-success-body_plural": "You have successfully uploaded {{count}} files to {{name}}.", - "clipboard": "Clipboard", - "select-directory": "" - }, - "nextcloud-file-picker": { - "open-nextcloud-file-picker": "Select files from your {{name}}", - "folder-home": "Jump to the home directory", - "select-files": "Select files", - "select-files-btn": "Select file", - "select-files-btn_plural": "Select {{count}} files", - "refresh-nextcloud-file-picker": "Connect again", - "loadpath-nextcloud-file-picker": "Loading directory from {{name}}.", - "load-path-link": "Go to {{path}}", - "auth-progress": "Authentification in progress", - "last-modified": "Last modified", - "mime-type": "Type", - "filename": "Filename", - "size": "Size", - "init-text-1": "Chose your files from {{name}}.", - "init-text-2": "You need to authenticate first.", - "auth-info": "A new page will open to connect your account.", - "connect-nextcloud": "Connect {{name}}", - "no-data": "No data avaible in this folder.", - "no-data-type": "No data avaible in this folder.", - "no-favorites": "No favorites of the relevant type were found. Define files and folders as favorites in your {{name}} to display them here", - "no-recent-files": "No relevant files and folders were found within the last 3 months.", - "webdav-error": "Something went wrong", - "add-folder-error": "The resource \"{{folder}}\" you tried to create already exists.", - "add-folder-error-empty": "The folder name can not be empty.", - "add-folder-success": "The folder '{{folder}}' was created successfully.", - "add-folder": "Add new folder", - "add-folder-open": "Open new folder dialogue", - "add-folder-close": "Close new folder dialogue", - "new-folder-placeholder": "New folder", - "load-in-folder": "Load into the current directory", - "load-to-folder": "Upload to the selected folder", - "replace-title-1": "There is already a file with the name ", - "replace-title-2": " in this location", - "replace-text": "What do you want to do", - "replace-new_name": "New Name", - "replace-replace": "Replace", - "replace-skip": "Ignore", - "replace-cancel": "Cancel", - "replace-cancel-all": "Cancel all", - "replace-mode-all": "Do this for the next conflicts", - "something-went-wrong": "Something went wrong. Please reload.", - "upload-to": "Uploading to {{- path}} ...", - "readonly": "You are not allowed to uploade files in this directory.", - "onlycreate": "You are only allowed to create new files in this directory.", - "onlyedit": "You are only allowed to edit files in this directory.", - "abort": "Cancel process", - "abort-message": "The process was canceled.", - "error-save-to-favorites": "Saving to Favorites not possible! Please select a folder within the Favorites.", - "error-save-to-recent": "Saving to Recent Files not possible! Please select a folder within the Recent Files.", - "recent-files-link-text": "Recent Files", - "favorites-link-text": "My Favorites", - "remember-me": "Stay connected with {{name}}", - "log-out": "Disconnect", - "open-submenu": "Open submenu", - "show-only-my-files": "Show only my files", - "favorites-title": "Favorites", - "recent-files-title": "Recent Files", - "my-recent-files-title": "My Recent Files", - "my-recent-files-link-text": "My Recent Files", - "all-recent-files-link-text": "All Recent Files" - }, - "clipboard": { - "add-files": "Add files to clipboard", - "add-files-btn": "Add files", - "remove-all": "Remove all files from the clipboard", - "remove-all-btn": "Remove all", - "remove-count": "Remove file from the clipboard", - "remove-count_plural": "Remove {{count}} files from the clipboard", - "remove-count-btn": "Remove file", - "remove-count-btn_plural": "Remove {{count}} files", - "save-all": "Save all files from the clipboard", - "save-all-btn": "Save all", - "save-count-btn": "Save file", - "save-count-btn_plural": "Save {{count}} files", - "save-count": "Save one file from the clipboard", - "save-count_plural": "Save {{count}} files from the clipboard", - "file-name": "Name", - "file-size": "Size", - "file-type": "Type", - "file-mod": "Last modified", - "no-data": "There are no files", - "saved-files-title": "File successfully filed", - "saved-files-title_plural": "Files successfully filed", - "saved-files-body": "A file was successfully stored temporarily in the clipboard and can now be used within this application.", - "saved-files-body_plural": "{{count}} files were successfully stored temporarily in the clipboard and can now be used within this application.", - "clear-clipboard-title": "Clipboard cleared", - "clear-clipboard-body": "The clipboard was successfully cleared.", - "clear-count-clipboard-title": "File removed", - "clear-count-clipboard-title_plural": "Files removed", - "clear-count-clipboard-body": "One file was successfully removed from clipboard.", - "clear-count-clipboard-body_plural": "{{count}} files were successfully removed from clipboard.", - "file-warning": "Attention!", - "file-warning-body": "There is still a file on the clipboard. The clipboard is discarded when you exit the page.", - "file-warning-body_plural": "There are still {{count}} files on the clipboard. The clipboard is discarded when you exit the page.", - "upload-area-text": "In this area you can upload documents up to a size of 32MB via Drag & Drop or by selecting them directly. ", - "upload-button-label": "Load to clipboard", - "warning": "Attention! If you close the browser or reload the page the existing clipboard is automatically discarded!", - "source-title": "Select files from clipboard", - "source-btn": "Select file", - "source-btn_plural": "Select {{count}} files", - "source-btn-none": "Select files", - "sink-title": "Store files on the clipboard", - "sink-btn": "Store {{count}} file", - "sink-btn_plural": "Store {{count}} files", - "select-all": "Select all", - "select-nothing": "Select nothing" - } + "demo-title": "File Upload Demo", + "required-server": "You need an upload server listening at <a href=\"{{- url}}\"><tt>{{- url}}</tt></a> to receive the files...", + "intro": "Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region.", + "upload-label": "Select some files", + "file-source": { + "modal-close": "Close dialog", + "nav-local": "My device", + "no-usable-files-in-zip": "ZIP file does not contain any usable files", + "no-usable-files-hint": "Upload a ZIP file with file type(s) of ", + "clipboard": "Clipboard", + "mime-type-title": "Unsupported file format", + "mime-type-body": "The file format is not supported by this application.", + "too-big-file-title": "The file is too big!", + "too-big-file-body": "The file can have a maximum of {{size}}.", + "open-menu": "" + }, + "file-sink": { + "local-intro": "Download {{count}} file", + "local-button": "Download file", + "modal-close": "Close dialog", + "nav-local": "My device", + "upload-success-title": "Successful uploaded", + "upload-success-body": "You have successfully uploaded {{count}} file to {{name}}.", + "upload-success-body_plural": "You have successfully uploaded {{count}} files to {{name}}.", + "clipboard": "Clipboard", + "select-directory": "" + }, + "nextcloud-file-picker": { + "open-nextcloud-file-picker": "Select files from your {{name}}", + "folder-home": "Jump to the home directory", + "select-files": "Select files", + "select-files-btn": "Select file", + "select-files-btn_plural": "Select {{count}} files", + "refresh-nextcloud-file-picker": "Connect again", + "loadpath-nextcloud-file-picker": "Loading directory from {{name}}.", + "load-path-link": "Go to {{path}}", + "auth-progress": "Authentification in progress", + "last-modified": "Last modified", + "mime-type": "Type", + "filename": "Filename", + "size": "Size", + "init-text-1": "Chose your files from {{name}}.", + "init-text-2": "You need to authenticate first.", + "auth-info": "A new page will open to connect your account.", + "connect-nextcloud": "Connect {{name}}", + "no-data": "No data avaible in this folder.", + "no-data-type": "No data avaible in this folder.", + "no-favorites": "No favorites of the relevant type were found. Define files and folders as favorites in your {{name}} to display them here", + "no-recent-files": "No relevant files and folders were found within the last 3 months.", + "webdav-error": "Something went wrong", + "add-folder-error": "The resource \"{{folder}}\" you tried to create already exists.", + "add-folder-error-empty": "The folder name can not be empty.", + "add-folder-success": "The folder '{{folder}}' was created successfully.", + "add-folder": "Add new folder", + "add-folder-open": "Open new folder dialogue", + "add-folder-close": "Close new folder dialogue", + "new-folder-placeholder": "New folder", + "load-in-folder": "Load into the current directory", + "load-to-folder": "Upload to the selected folder", + "replace-title-1": "There is already a file with the name ", + "replace-title-2": " in this location", + "replace-text": "What do you want to do", + "replace-new_name": "New Name", + "replace-replace": "Replace", + "replace-skip": "Ignore", + "replace-cancel": "Cancel", + "replace-cancel-all": "Cancel all", + "replace-mode-all": "Do this for the next conflicts", + "something-went-wrong": "Something went wrong. Please reload.", + "upload-to": "Uploading to {{- path}} ...", + "readonly": "You are not allowed to uploade files in this directory.", + "onlycreate": "You are only allowed to create new files in this directory.", + "onlyedit": "You are only allowed to edit files in this directory.", + "abort": "Cancel process", + "abort-message": "The process was canceled.", + "error-save-to-favorites": "Saving to Favorites not possible! Please select a folder within the Favorites.", + "error-save-to-recent": "Saving to Recent Files not possible! Please select a folder within the Recent Files.", + "recent-files-link-text": "Recent Files", + "favorites-link-text": "My Favorites", + "remember-me": "Stay connected with {{name}}", + "log-out": "Disconnect", + "open-submenu": "Open submenu", + "show-only-my-files": "Show only my files", + "favorites-title": "Favorites", + "recent-files-title": "Recent Files", + "my-recent-files-title": "My Recent Files", + "my-recent-files-link-text": "My Recent Files", + "all-recent-files-link-text": "All Recent Files" + }, + "clipboard": { + "add-files": "Add files to clipboard", + "add-files-btn": "Add files", + "remove-all": "Remove all files from the clipboard", + "remove-all-btn": "Remove all", + "remove-count": "Remove file from the clipboard", + "remove-count_plural": "Remove {{count}} files from the clipboard", + "remove-count-btn": "Remove file", + "remove-count-btn_plural": "Remove {{count}} files", + "save-all": "Save all files from the clipboard", + "save-all-btn": "Save all", + "save-count-btn": "Save file", + "save-count-btn_plural": "Save {{count}} files", + "save-count": "Save one file from the clipboard", + "save-count_plural": "Save {{count}} files from the clipboard", + "file-name": "Name", + "file-size": "Size", + "file-type": "Type", + "file-mod": "Last modified", + "no-data": "There are no files", + "saved-files-title": "File successfully filed", + "saved-files-title_plural": "Files successfully filed", + "saved-files-body": "A file was successfully stored temporarily in the clipboard and can now be used within this application.", + "saved-files-body_plural": "{{count}} files were successfully stored temporarily in the clipboard and can now be used within this application.", + "clear-clipboard-title": "Clipboard cleared", + "clear-clipboard-body": "The clipboard was successfully cleared.", + "clear-count-clipboard-title": "File removed", + "clear-count-clipboard-title_plural": "Files removed", + "clear-count-clipboard-body": "One file was successfully removed from clipboard.", + "clear-count-clipboard-body_plural": "{{count}} files were successfully removed from clipboard.", + "file-warning": "Attention!", + "file-warning-body": "There is still a file on the clipboard. The clipboard is discarded when you exit the page.", + "file-warning-body_plural": "There are still {{count}} files on the clipboard. The clipboard is discarded when you exit the page.", + "upload-area-text": "In this area you can upload documents up to a size of 32MB via Drag & Drop or by selecting them directly. ", + "upload-button-label": "Load to clipboard", + "warning": "Attention! If you close the browser or reload the page the existing clipboard is automatically discarded!", + "source-title": "Select files from clipboard", + "source-btn": "Select file", + "source-btn_plural": "Select {{count}} files", + "source-btn-none": "Select files", + "sink-title": "Store files on the clipboard", + "sink-btn": "Store {{count}} file", + "sink-btn_plural": "Store {{count}} files", + "select-all": "Select all", + "select-nothing": "Select nothing" + } } diff --git a/packages/file-handling/src/index.js b/packages/file-handling/src/index.js index d6c793d0dc423aaab642a840b5e2f0b0ff9b8a5c..b5ab4486e35e4490b0ac508b340e55abb5227f56 100644 --- a/packages/file-handling/src/index.js +++ b/packages/file-handling/src/index.js @@ -1,2 +1,2 @@ export {FileSource} from './file-source'; -export {FileSink} from './file-sink'; \ No newline at end of file +export {FileSink} from './file-sink'; diff --git a/packages/file-handling/src/micromodal.es.js b/packages/file-handling/src/micromodal.es.js index e79dcf78afd669f1ca55ab1da393ceb9edc2a8b9..ce57377e51638ce65556fc1b23213378f2032e3e 100644 --- a/packages/file-handling/src/micromodal.es.js +++ b/packages/file-handling/src/micromodal.es.js @@ -1,449 +1,515 @@ // see https://github.com/ghosh/Micromodal/pull/351 function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } } function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } } function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; } function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); + return ( + _arrayWithoutHoles(arr) || + _iterableToArray(arr) || + _unsupportedIterableToArray(arr) || + _nonIterableSpread() + ); } function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) return _arrayLikeToArray(arr); + if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(iter) { - if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); + if (typeof Symbol !== 'undefined' && Symbol.iterator in Object(iter)) return Array.from(iter); } function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(n); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + if (!o) return; + if (typeof o === 'string') return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === 'Object' && o.constructor) n = o.constructor.name; + if (n === 'Map' || n === 'Set') return Array.from(n); + if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) + return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; + if (len == null || len > arr.length) len = arr.length; - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - return arr2; + return arr2; } function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + throw new TypeError( + 'Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.' + ); } -var MicroModal = function () { - - var FOCUSABLE_ELEMENTS = ['a[href]', 'area[href]', 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', 'select:not([disabled]):not([aria-hidden])', 'textarea:not([disabled]):not([aria-hidden])', 'button:not([disabled]):not([aria-hidden])', 'iframe', 'object', 'embed', '[contenteditable]', '[tabindex]:not([tabindex^="-"])']; - - var Modal = /*#__PURE__*/function () { - function Modal(_ref) { - var targetModal = _ref.targetModal, - _ref$triggers = _ref.triggers, - triggers = _ref$triggers === void 0 ? [] : _ref$triggers, - _ref$onShow = _ref.onShow, - onShow = _ref$onShow === void 0 ? function () {} : _ref$onShow, - _ref$onClose = _ref.onClose, - onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose, - _ref$openTrigger = _ref.openTrigger, - openTrigger = _ref$openTrigger === void 0 ? 'data-micromodal-trigger' : _ref$openTrigger, - _ref$closeTrigger = _ref.closeTrigger, - closeTrigger = _ref$closeTrigger === void 0 ? 'data-micromodal-close' : _ref$closeTrigger, - _ref$openClass = _ref.openClass, - openClass = _ref$openClass === void 0 ? 'is-open' : _ref$openClass, - _ref$disableScroll = _ref.disableScroll, - disableScroll = _ref$disableScroll === void 0 ? false : _ref$disableScroll, - _ref$disableFocus = _ref.disableFocus, - disableFocus = _ref$disableFocus === void 0 ? false : _ref$disableFocus, - _ref$awaitCloseAnimat = _ref.awaitCloseAnimation, - awaitCloseAnimation = _ref$awaitCloseAnimat === void 0 ? false : _ref$awaitCloseAnimat, - _ref$awaitOpenAnimati = _ref.awaitOpenAnimation, - awaitOpenAnimation = _ref$awaitOpenAnimati === void 0 ? false : _ref$awaitOpenAnimati, - _ref$debugMode = _ref.debugMode, - debugMode = _ref$debugMode === void 0 ? false : _ref$debugMode; - - _classCallCheck(this, Modal); - - // Save a reference of the modal - this.modal = this.modal = typeof targetModal === "string" ? document.getElementById(targetModal) : targetModal; // Save a reference to the passed config - - this.config = { - debugMode: debugMode, - disableScroll: disableScroll, - openTrigger: openTrigger, - closeTrigger: closeTrigger, - openClass: openClass, - onShow: onShow, - onClose: onClose, - awaitCloseAnimation: awaitCloseAnimation, - awaitOpenAnimation: awaitOpenAnimation, - disableFocus: disableFocus - }; // Register click events only if pre binding eventListeners - - if (triggers.length > 0) this.registerTriggers.apply(this, _toConsumableArray(triggers)); // pre bind functions for event listeners - - this.onClick = this.onClick.bind(this); - this.onKeydown = this.onKeydown.bind(this); - } +var MicroModal = (function () { + var FOCUSABLE_ELEMENTS = [ + 'a[href]', + 'area[href]', + 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', + 'select:not([disabled]):not([aria-hidden])', + 'textarea:not([disabled]):not([aria-hidden])', + 'button:not([disabled]):not([aria-hidden])', + 'iframe', + 'object', + 'embed', + '[contenteditable]', + '[tabindex]:not([tabindex^="-"])', + ]; + + var Modal = /*#__PURE__*/ (function () { + function Modal(_ref) { + var targetModal = _ref.targetModal, + _ref$triggers = _ref.triggers, + triggers = _ref$triggers === void 0 ? [] : _ref$triggers, + _ref$onShow = _ref.onShow, + onShow = _ref$onShow === void 0 ? function () {} : _ref$onShow, + _ref$onClose = _ref.onClose, + onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose, + _ref$openTrigger = _ref.openTrigger, + openTrigger = + _ref$openTrigger === void 0 ? 'data-micromodal-trigger' : _ref$openTrigger, + _ref$closeTrigger = _ref.closeTrigger, + closeTrigger = + _ref$closeTrigger === void 0 ? 'data-micromodal-close' : _ref$closeTrigger, + _ref$openClass = _ref.openClass, + openClass = _ref$openClass === void 0 ? 'is-open' : _ref$openClass, + _ref$disableScroll = _ref.disableScroll, + disableScroll = _ref$disableScroll === void 0 ? false : _ref$disableScroll, + _ref$disableFocus = _ref.disableFocus, + disableFocus = _ref$disableFocus === void 0 ? false : _ref$disableFocus, + _ref$awaitCloseAnimat = _ref.awaitCloseAnimation, + awaitCloseAnimation = + _ref$awaitCloseAnimat === void 0 ? false : _ref$awaitCloseAnimat, + _ref$awaitOpenAnimati = _ref.awaitOpenAnimation, + awaitOpenAnimation = + _ref$awaitOpenAnimati === void 0 ? false : _ref$awaitOpenAnimati, + _ref$debugMode = _ref.debugMode, + debugMode = _ref$debugMode === void 0 ? false : _ref$debugMode; + + _classCallCheck(this, Modal); + + // Save a reference of the modal + this.modal = this.modal = + typeof targetModal === 'string' + ? document.getElementById(targetModal) + : targetModal; // Save a reference to the passed config + + this.config = { + debugMode: debugMode, + disableScroll: disableScroll, + openTrigger: openTrigger, + closeTrigger: closeTrigger, + openClass: openClass, + onShow: onShow, + onClose: onClose, + awaitCloseAnimation: awaitCloseAnimation, + awaitOpenAnimation: awaitOpenAnimation, + disableFocus: disableFocus, + }; // Register click events only if pre binding eventListeners + + if (triggers.length > 0) + this.registerTriggers.apply(this, _toConsumableArray(triggers)); // pre bind functions for event listeners + + this.onClick = this.onClick.bind(this); + this.onKeydown = this.onKeydown.bind(this); + } + /** + * Loops through all openTriggers and binds click event + * @param {array} triggers [Array of node elements] + * @return {void} + */ + + _createClass(Modal, [ + { + key: 'registerTriggers', + value: function registerTriggers() { + var _this = this; + + for ( + var _len = arguments.length, triggers = new Array(_len), _key = 0; + _key < _len; + _key++ + ) { + triggers[_key] = arguments[_key]; + } + + triggers.filter(Boolean).forEach(function (trigger) { + trigger.addEventListener('click', function (event) { + return _this.showModal(event); + }); + }); + }, + }, + { + key: 'showModal', + value: function showModal() { + var _this2 = this; + + var event = + arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + this.activeElement = document.activeElement; + this.modal.setAttribute('aria-hidden', 'false'); + this.modal.classList.add(this.config.openClass); + this.scrollBehaviour('disable'); + this.addEventListeners(); + + if (this.config.awaitOpenAnimation) { + var handler = function handler() { + _this2.modal.removeEventListener('animationend', handler, false); + + _this2.setFocusToFirstNode(); + }; + + this.modal.addEventListener('animationend', handler, false); + } else { + this.setFocusToFirstNode(); + } + + this.config.onShow(this.modal, this.activeElement, event); + }, + }, + { + key: 'closeModal', + value: function closeModal() { + var event = + arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var modal = this.modal; + this.modal.setAttribute('aria-hidden', 'true'); + this.removeEventListeners(); + this.scrollBehaviour('enable'); + + if (this.activeElement && this.activeElement.focus) { + this.activeElement.focus(); + } + + this.config.onClose(this.modal, this.activeElement, event); + + if (this.config.awaitCloseAnimation) { + var openClass = this.config.openClass; // <- old school ftw + + this.modal.addEventListener( + 'animationend', + function handler() { + modal.classList.remove(openClass); + modal.removeEventListener('animationend', handler, false); + }, + false + ); + } else { + modal.classList.remove(this.config.openClass); + } + }, + }, + { + key: 'closeModalById', + value: function closeModalById(targetModal) { + // added support to pass on an element or an id -> for webcomponents + if (targetModal instanceof HTMLElement) { + this.modal = targetModal; + } else { + this.model = document.getElementById(targetModal); + } + if (this.modal) this.closeModal(); + }, + }, + { + key: 'scrollBehaviour', + value: function scrollBehaviour(toggle) { + if (!this.config.disableScroll) return; + var body = document.querySelector('body'); + + switch (toggle) { + case 'enable': + Object.assign(body.style, { + overflow: '', + }); + break; + + case 'disable': + Object.assign(body.style, { + overflow: 'hidden', + }); + break; + } + }, + }, + { + key: 'addEventListeners', + value: function addEventListeners() { + this.modal.addEventListener('touchstart', this.onClick); + this.modal.addEventListener('click', this.onClick); + document.addEventListener('keydown', this.onKeydown); + }, + }, + { + key: 'removeEventListeners', + value: function removeEventListeners() { + this.modal.removeEventListener('touchstart', this.onClick); + this.modal.removeEventListener('click', this.onClick); + document.removeEventListener('keydown', this.onKeydown); + }, + }, + { + key: 'onClick', + value: function onClick(event) { + if (event.target.hasAttribute(this.config.closeTrigger)) { + this.closeModal(event); + } + }, + }, + { + key: 'onKeydown', + value: function onKeydown(event) { + if (event.keyCode === 27) this.closeModal(event); // esc + + if (event.keyCode === 9) this.retainFocus(event); // tab + }, + }, + { + key: 'getFocusableNodes', + value: function getFocusableNodes() { + var nodes = this.modal.querySelectorAll(FOCUSABLE_ELEMENTS); + return Array.apply(void 0, _toConsumableArray(nodes)); + }, + /** + * Tries to set focus on a node which is not a close trigger + * if no other nodes exist then focuses on first close trigger + */ + }, + { + key: 'setFocusToFirstNode', + value: function setFocusToFirstNode() { + var _this3 = this; + + if (this.config.disableFocus) return; + var focusableNodes = this.getFocusableNodes(); // no focusable nodes + + if (focusableNodes.length === 0) return; // remove nodes on whose click, the modal closes + // could not think of a better name :( + + var nodesWhichAreNotCloseTargets = focusableNodes.filter(function (node) { + return !node.hasAttribute(_this3.config.closeTrigger); + }); + if (nodesWhichAreNotCloseTargets.length > 0) + nodesWhichAreNotCloseTargets[0].focus(); + if (nodesWhichAreNotCloseTargets.length === 0) focusableNodes[0].focus(); + }, + }, + { + key: 'retainFocus', + value: function retainFocus(event) { + var focusableNodes = this.getFocusableNodes(); // no focusable nodes + + if (focusableNodes.length === 0) return; + /** + * Filters nodes which are hidden to prevent + * focus leak outside modal + */ + + focusableNodes = focusableNodes.filter(function (node) { + return node.offsetParent !== null; + }); // if disableFocus is true + + if (!this.modal.contains(document.activeElement)) { + focusableNodes[0].focus(); + } else { + var focusedItemIndex = focusableNodes.indexOf(document.activeElement); + + if (event.shiftKey && focusedItemIndex === 0) { + focusableNodes[focusableNodes.length - 1].focus(); + event.preventDefault(); + } + + if ( + !event.shiftKey && + focusableNodes.length > 0 && + focusedItemIndex === focusableNodes.length - 1 + ) { + focusableNodes[0].focus(); + event.preventDefault(); + } + } + }, + }, + ]); + + return Modal; + })(); /** - * Loops through all openTriggers and binds click event - * @param {array} triggers [Array of node elements] - * @return {void} + * Modal prototype ends. + * Here on code is responsible for detecting and + * auto binding event handlers on modal triggers */ + // Keep a reference to the opened modal + var activeModal = null; + /** + * Generates an associative array of modals and it's + * respective triggers + * @param {array} triggers An array of all triggers + * @param {string} triggerAttr The data-attribute which triggers the module + * @return {array} + */ - _createClass(Modal, [{ - key: "registerTriggers", - value: function registerTriggers() { - var _this = this; - - for (var _len = arguments.length, triggers = new Array(_len), _key = 0; _key < _len; _key++) { - triggers[_key] = arguments[_key]; - } - - triggers.filter(Boolean).forEach(function (trigger) { - trigger.addEventListener('click', function (event) { - return _this.showModal(event); - }); + var generateTriggerMap = function generateTriggerMap(triggers, triggerAttr) { + var triggerMap = []; + triggers.forEach(function (trigger) { + var targetModal = trigger.attributes[triggerAttr].value; + if (triggerMap[targetModal] === undefined) triggerMap[targetModal] = []; + triggerMap[targetModal].push(trigger); }); - } - }, { - key: "showModal", - value: function showModal() { - var _this2 = this; - - var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - this.activeElement = document.activeElement; - this.modal.setAttribute('aria-hidden', 'false'); - this.modal.classList.add(this.config.openClass); - this.scrollBehaviour('disable'); - this.addEventListeners(); - - if (this.config.awaitOpenAnimation) { - var handler = function handler() { - _this2.modal.removeEventListener('animationend', handler, false); - - _this2.setFocusToFirstNode(); - }; - - this.modal.addEventListener('animationend', handler, false); - } else { - this.setFocusToFirstNode(); - } + return triggerMap; + }; + /** + * Validates whether a modal of the given id exists + * in the DOM + * @param {number} id The id of the modal + * @return {boolean} + */ - this.config.onShow(this.modal, this.activeElement, event); - } - }, { - key: "closeModal", - value: function closeModal() { - var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - var modal = this.modal; - this.modal.setAttribute('aria-hidden', 'true'); - this.removeEventListeners(); - this.scrollBehaviour('enable'); - - if (this.activeElement && this.activeElement.focus) { - this.activeElement.focus(); + var validateModalPresence = function validateModalPresence(id) { + if (!document.getElementById(id)) { + console.warn( + "MicroModal: \u2757Seems like you have missed %c'".concat(id, "'"), + 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', + 'ID somewhere in your code. Refer example below to resolve it.' + ); + console.warn( + '%cExample:', + 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', + '<div class="modal" id="'.concat(id, '"></div>') + ); + return false; } + }; + /** + * Validates if there are modal triggers present + * in the DOM + * @param {array} triggers An array of data-triggers + * @return {boolean} + */ - this.config.onClose(this.modal, this.activeElement, event); - - if (this.config.awaitCloseAnimation) { - var openClass = this.config.openClass; // <- old school ftw - - this.modal.addEventListener('animationend', function handler() { - modal.classList.remove(openClass); - modal.removeEventListener('animationend', handler, false); - }, false); - } else { - modal.classList.remove(this.config.openClass); + var validateTriggerPresence = function validateTriggerPresence(triggers) { + if (triggers.length <= 0) { + console.warn( + "MicroModal: \u2757Please specify at least one %c'micromodal-trigger'", + 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', + 'data attribute.' + ); + console.warn( + '%cExample:', + 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', + '<a href="#" data-micromodal-trigger="my-modal"></a>' + ); + return false; } - } - }, { - key: "closeModalById", - value: function closeModalById(targetModal) { - // added support to pass on an element or an id -> for webcomponents - if (targetModal instanceof HTMLElement) { - this.modal = targetModal; - } - else { - this.model = document.getElementById(targetModal); - } - if (this.modal) this.closeModal(); - } - }, { - key: "scrollBehaviour", - value: function scrollBehaviour(toggle) { - if (!this.config.disableScroll) return; - var body = document.querySelector('body'); - - switch (toggle) { - case 'enable': - Object.assign(body.style, { - overflow: '' - }); - break; - - case 'disable': - Object.assign(body.style, { - overflow: 'hidden' - }); - break; - } - } - }, { - key: "addEventListeners", - value: function addEventListeners() { - this.modal.addEventListener('touchstart', this.onClick); - this.modal.addEventListener('click', this.onClick); - document.addEventListener('keydown', this.onKeydown); - } - }, { - key: "removeEventListeners", - value: function removeEventListeners() { - this.modal.removeEventListener('touchstart', this.onClick); - this.modal.removeEventListener('click', this.onClick); - document.removeEventListener('keydown', this.onKeydown); - } - }, { - key: "onClick", - value: function onClick(event) { - if (event.target.hasAttribute(this.config.closeTrigger)) { - this.closeModal(event); - } - } - }, { - key: "onKeydown", - value: function onKeydown(event) { - if (event.keyCode === 27) this.closeModal(event); // esc - - if (event.keyCode === 9) this.retainFocus(event); // tab - } - }, { - key: "getFocusableNodes", - value: function getFocusableNodes() { - var nodes = this.modal.querySelectorAll(FOCUSABLE_ELEMENTS); - return Array.apply(void 0, _toConsumableArray(nodes)); - } - /** - * Tries to set focus on a node which is not a close trigger - * if no other nodes exist then focuses on first close trigger - */ - - }, { - key: "setFocusToFirstNode", - value: function setFocusToFirstNode() { - var _this3 = this; - - if (this.config.disableFocus) return; - var focusableNodes = this.getFocusableNodes(); // no focusable nodes - - if (focusableNodes.length === 0) return; // remove nodes on whose click, the modal closes - // could not think of a better name :( - - var nodesWhichAreNotCloseTargets = focusableNodes.filter(function (node) { - return !node.hasAttribute(_this3.config.closeTrigger); - }); - if (nodesWhichAreNotCloseTargets.length > 0) nodesWhichAreNotCloseTargets[0].focus(); - if (nodesWhichAreNotCloseTargets.length === 0) focusableNodes[0].focus(); - } - }, { - key: "retainFocus", - value: function retainFocus(event) { - var focusableNodes = this.getFocusableNodes(); // no focusable nodes - - if (focusableNodes.length === 0) return; - /** - * Filters nodes which are hidden to prevent - * focus leak outside modal - */ - - focusableNodes = focusableNodes.filter(function (node) { - return node.offsetParent !== null; - }); // if disableFocus is true - - if (!this.modal.contains(document.activeElement)) { - focusableNodes[0].focus(); - } else { - var focusedItemIndex = focusableNodes.indexOf(document.activeElement); + }; + /** + * Checks if triggers and their corresponding modals + * are present in the DOM + * @param {array} triggers Array of DOM nodes which have data-triggers + * @param {array} triggerMap Associative array of modals and their triggers + * @return {boolean} + */ - if (event.shiftKey && focusedItemIndex === 0) { - focusableNodes[focusableNodes.length - 1].focus(); - event.preventDefault(); - } + var validateArgs = function validateArgs(triggers, triggerMap) { + validateTriggerPresence(triggers); + if (!triggerMap) return true; - if (!event.shiftKey && focusableNodes.length > 0 && focusedItemIndex === focusableNodes.length - 1) { - focusableNodes[0].focus(); - event.preventDefault(); - } + for (var id in triggerMap) { + validateModalPresence(id); } - } - }]); - - return Modal; - }(); - /** - * Modal prototype ends. - * Here on code is responsible for detecting and - * auto binding event handlers on modal triggers - */ - // Keep a reference to the opened modal - - - var activeModal = null; - /** - * Generates an associative array of modals and it's - * respective triggers - * @param {array} triggers An array of all triggers - * @param {string} triggerAttr The data-attribute which triggers the module - * @return {array} - */ - - var generateTriggerMap = function generateTriggerMap(triggers, triggerAttr) { - var triggerMap = []; - triggers.forEach(function (trigger) { - var targetModal = trigger.attributes[triggerAttr].value; - if (triggerMap[targetModal] === undefined) triggerMap[targetModal] = []; - triggerMap[targetModal].push(trigger); - }); - return triggerMap; - }; - /** - * Validates whether a modal of the given id exists - * in the DOM - * @param {number} id The id of the modal - * @return {boolean} - */ - - - var validateModalPresence = function validateModalPresence(id) { - if (!document.getElementById(id)) { - console.warn("MicroModal: \u2757Seems like you have missed %c'".concat(id, "'"), 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', 'ID somewhere in your code. Refer example below to resolve it.'); - console.warn("%cExample:", 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', "<div class=\"modal\" id=\"".concat(id, "\"></div>")); - return false; - } - }; - /** - * Validates if there are modal triggers present - * in the DOM - * @param {array} triggers An array of data-triggers - * @return {boolean} - */ - - - var validateTriggerPresence = function validateTriggerPresence(triggers) { - if (triggers.length <= 0) { - console.warn("MicroModal: \u2757Please specify at least one %c'micromodal-trigger'", 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', 'data attribute.'); - console.warn("%cExample:", 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', "<a href=\"#\" data-micromodal-trigger=\"my-modal\"></a>"); - return false; - } - }; - /** - * Checks if triggers and their corresponding modals - * are present in the DOM - * @param {array} triggers Array of DOM nodes which have data-triggers - * @param {array} triggerMap Associative array of modals and their triggers - * @return {boolean} - */ - - - var validateArgs = function validateArgs(triggers, triggerMap) { - validateTriggerPresence(triggers); - if (!triggerMap) return true; - - for (var id in triggerMap) { - validateModalPresence(id); - } - - return true; - }; - /** - * Binds click handlers to all modal triggers - * @param {object} config [description] - * @return void - */ - - - var init = function init(config) { - // Create an config object with default openTrigger - var options = Object.assign({}, { - openTrigger: 'data-micromodal-trigger' - }, config); // Collects all the nodes with the trigger - - var triggers = _toConsumableArray(document.querySelectorAll("[".concat(options.openTrigger, "]"))); // Makes a mappings of modals with their trigger nodes - - - var triggerMap = generateTriggerMap(triggers, options.openTrigger); // Checks if modals and triggers exist in dom - - if (options.debugMode === true && validateArgs(triggers, triggerMap) === false) return; // For every target modal creates a new instance - - for (var key in triggerMap) { - var value = triggerMap[key]; - options.targetModal = key; - options.triggers = _toConsumableArray(value); - activeModal = new Modal(options); // eslint-disable-line no-new - } - }; - /** - * Shows a particular modal - * @param {string} targetModal [The id of the modal to display] - * @param {object} config [The configuration object to pass] - * @return {void} - */ + return true; + }; + /** + * Binds click handlers to all modal triggers + * @param {object} config [description] + * @return void + */ - var show = function show(targetModal, config) { - var options = config || {}; - options.targetModal = targetModal; // Checks if modals and triggers exist in dom + var init = function init(config) { + // Create an config object with default openTrigger + var options = Object.assign( + {}, + { + openTrigger: 'data-micromodal-trigger', + }, + config + ); // Collects all the nodes with the trigger + + var triggers = _toConsumableArray( + document.querySelectorAll('['.concat(options.openTrigger, ']')) + ); // Makes a mappings of modals with their trigger nodes + + var triggerMap = generateTriggerMap(triggers, options.openTrigger); // Checks if modals and triggers exist in dom + + if (options.debugMode === true && validateArgs(triggers, triggerMap) === false) return; // For every target modal creates a new instance + + for (var key in triggerMap) { + var value = triggerMap[key]; + options.targetModal = key; + options.triggers = _toConsumableArray(value); + activeModal = new Modal(options); // eslint-disable-line no-new + } + }; + /** + * Shows a particular modal + * @param {string} targetModal [The id of the modal to display] + * @param {object} config [The configuration object to pass] + * @return {void} + */ - if (options.debugMode === true && validateModalPresence(targetModal) === false) return; // clear events in case previous modal wasn't close + var show = function show(targetModal, config) { + var options = config || {}; + options.targetModal = targetModal; // Checks if modals and triggers exist in dom - if (activeModal) activeModal.removeEventListeners(); // stores reference to active modal + if (options.debugMode === true && validateModalPresence(targetModal) === false) return; // clear events in case previous modal wasn't close - activeModal = new Modal(options); // eslint-disable-line no-new + if (activeModal) activeModal.removeEventListeners(); // stores reference to active modal - activeModal.showModal(); - }; - /** - * Closes the active modal - * @param {string} targetModal [The id of the modal to close] - * @return {void} - */ + activeModal = new Modal(options); // eslint-disable-line no-new + activeModal.showModal(); + }; + /** + * Closes the active modal + * @param {string} targetModal [The id of the modal to close] + * @return {void} + */ - var close = function close(targetModal) { - targetModal ? activeModal.closeModalById(targetModal) : activeModal.closeModal(); - }; + var close = function close(targetModal) { + targetModal ? activeModal.closeModalById(targetModal) : activeModal.closeModal(); + }; - return { - init: init, - show: show, - close: close - }; -}(); + return { + init: init, + show: show, + close: close, + }; +})(); window.MicroModal = MicroModal; export default MicroModal; diff --git a/packages/file-handling/src/nextcloud-file-picker.js b/packages/file-handling/src/nextcloud-file-picker.js index 6dc9b4ff2fb355805df96a556e2f932792a480a9..8736bc44a8219b642a64e1f25a53bdb93bdceb20 100644 --- a/packages/file-handling/src/nextcloud-file-picker.js +++ b/packages/file-handling/src/nextcloud-file-picker.js @@ -14,7 +14,6 @@ import {name as pkgName} from './../package.json'; import * as fileHandlingStyles from './styles'; import {encrypt, decrypt, parseJwt} from './crypto.js'; - /** * NextcloudFilePicker web component */ @@ -114,32 +113,32 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { activeDirectoryACL: {type: String, attribute: false}, abortUploadButton: {type: Boolean, attribute: false}, selectBtnDisabled: {type: Boolean, attribute: true}, - userName: { type: Boolean, attribute: false }, + userName: {type: Boolean, attribute: false}, storeSession: {type: Boolean, attribute: 'store-nextcloud-session'}, - disableRowClick: {type: Boolean, attribute: false }, + disableRowClick: {type: Boolean, attribute: false}, }; } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); break; - case "auth": + case 'auth': this._updateAuth(); break; - case "directoriesOnly": - if (this.directoriesOnly && this._("#select_all_wrapper")) { - this._("#select_all_wrapper").classList.remove("button-container"); - this._("#select_all_wrapper").classList.add("hidden"); + case 'directoriesOnly': + if (this.directoriesOnly && this._('#select_all_wrapper')) { + this._('#select_all_wrapper').classList.remove('button-container'); + this._('#select_all_wrapper').classList.add('hidden'); } - if (!this.directoriesOnly && this._("#select_all_wrapper")) { - this._("#select_all_wrapper").classList.add("button-container"); - this._("#select_all_wrapper").classList.remove("hidden"); + if (!this.directoriesOnly && this._('#select_all_wrapper')) { + this._('#select_all_wrapper').classList.add('button-container'); + this._('#select_all_wrapper').classList.remove('hidden'); } } - }); + }); super.update(changedProperties); } @@ -153,13 +152,13 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { async firstUpdated() { // Give the browser a chance to paint await new Promise((r) => setTimeout(r, 0)); - if (this._("#select_all")) { + if (this._('#select_all')) { let boundSelectHandler = this.selectAllFiles.bind(this); - this._("#select_all").addEventListener('click', boundSelectHandler); + this._('#select_all').addEventListener('click', boundSelectHandler); } - if (this.directoriesOnly && this._("#select_all_wrapper")) { - this._("#select_all_wrapper").classList.remove("button-container"); - this._("#select_all_wrapper").classList.add("hidden"); + if (this.directoriesOnly && this._('#select_all_wrapper')) { + this._('#select_all_wrapper').classList.remove('button-container'); + this._('#select_all_wrapper').classList.add('hidden'); } } @@ -175,88 +174,101 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { // see: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage window.addEventListener('message', this._onReceiveWindowMessage); // see: http://tabulator.info/docs/4.7 - this.tabulatorTable = new Tabulator(this._("#directory-content-table"), { - layout: "fitColumns", + this.tabulatorTable = new Tabulator(this._('#directory-content-table'), { + layout: 'fitColumns', selectable: this.maxSelectedItems, - selectableRangeMode: "drag", - placeholder: this.directoriesOnly ? i18n.t('nextcloud-file-picker.no-data') : i18n.t('nextcloud-file-picker.no-data-type'), - responsiveLayout: "collapse", + selectableRangeMode: 'drag', + placeholder: this.directoriesOnly + ? i18n.t('nextcloud-file-picker.no-data') + : i18n.t('nextcloud-file-picker.no-data-type'), + responsiveLayout: 'collapse', responsiveLayoutCollapseStartOpen: false, resizableColumns: false, columns: [ { width: 32, minWidth: 32, - align: "center", + align: 'center', resizable: false, headerSort: false, - formatter: "responsiveCollapse" + formatter: 'responsiveCollapse', }, { - title: '<label id="select_all_wrapper" class="button-container select-all-icon">' + + title: + '<label id="select_all_wrapper" class="button-container select-all-icon">' + '<input type="checkbox" id="select_all" name="select_all" value="select_all">' + '<span class="checkmark" id="select_all_checkmark"></span>' + '</label>', - field: "type", - align: "center", + field: 'type', + align: 'center', headerSort: false, width: 50, responsive: 1, formatter: (cell, formatterParams, onRendered) => { - const icon_tag = that.getScopedTagName("dbp-icon"); - let disabled = this.directoriesOnly ? "nextcloud-picker-icon-disabled" : ""; - let icon = `<${icon_tag} name="empty-file" class="nextcloud-picker-icon ` + disabled + `"></${icon_tag}>`; - let html = (cell.getValue() === "directory") ? `<${icon_tag} name="folder" class="nextcloud-picker-icon"></${icon_tag}>` : icon; - let div = this.shadowRoot.createElement("div"); + const icon_tag = that.getScopedTagName('dbp-icon'); + let disabled = this.directoriesOnly + ? 'nextcloud-picker-icon-disabled' + : ''; + let icon = + `<${icon_tag} name="empty-file" class="nextcloud-picker-icon ` + + disabled + + `"></${icon_tag}>`; + let html = + cell.getValue() === 'directory' + ? `<${icon_tag} name="folder" class="nextcloud-picker-icon"></${icon_tag}>` + : icon; + let div = this.shadowRoot.createElement('div'); div.innerHTML = html; return div; - } + }, }, { title: i18n.t('nextcloud-file-picker.filename'), responsive: 0, widthGrow: 5, minWidth: 150, - field: "basename", - sorter: "alphanum", + field: 'basename', + sorter: 'alphanum', formatter: (cell) => { var data = cell.getRow().getData(); if (data.edit) { - cell.getElement().classList.add("fokus-edit"); + cell.getElement().classList.add('fokus-edit'); } return cell.getValue(); - } + }, }, { title: i18n.t('nextcloud-file-picker.size'), responsive: 4, widthGrow: 1, minWidth: 84, - field: "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: i18n.t('nextcloud-file-picker.mime-type'), responsive: 2, widthGrow: 1, minWidth: 58, - field: "mime", + field: 'mime', formatter: (cell, formatterParams, onRendered) => { if (typeof cell.getValue() === 'undefined') { - return ""; + return ''; } const [, fileSubType] = cell.getValue().split('/'); return fileSubType; - } + }, }, { title: i18n.t('nextcloud-file-picker.last-modified'), responsive: 3, widthGrow: 1, minWidth: 150, - field: "lastmod", + field: 'lastmod', sorter: (a, b, aRow, bRow, column, dir, sorterParams) => { const a_timestamp = Date.parse(a); const b_timestamp = Date.parse(b); @@ -266,30 +278,29 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { const d = Date.parse(cell.getValue()); const timestamp = new Date(d); const year = timestamp.getFullYear(); - const month = ("0" + (timestamp.getMonth() + 1)).slice(-2); - const date = ("0" + timestamp.getDate()).slice(-2); - const hours = ("0" + timestamp.getHours()).slice(-2); - const minutes = ("0" + timestamp.getMinutes()).slice(-2); - return date + "." + month + "." + year + " " + hours + ":" + minutes; - } + const month = ('0' + (timestamp.getMonth() + 1)).slice(-2); + const date = ('0' + timestamp.getDate()).slice(-2); + const hours = ('0' + timestamp.getHours()).slice(-2); + const minutes = ('0' + timestamp.getMinutes()).slice(-2); + return date + '.' + month + '.' + year + ' ' + hours + ':' + minutes; + }, }, - {title: "rights", field: "props.permissions", visible: false}, - {title: "acl", field: "props.acl-list.acl.acl-permissions", visible: false} + {title: 'rights', field: 'props.permissions', visible: false}, + {title: 'acl', field: 'props.acl-list.acl.acl-permissions', visible: false}, ], initialSort: [ - {column: "basename", dir: "asc"}, - {column: "type", dir: "asc"}, - + {column: 'basename', dir: 'asc'}, + {column: 'type', dir: 'asc'}, ], rowFormatter: (row) => { let data = row.getData(); - if (!this.checkFileType(data, this.allowedMimeTypes)) { - row.getElement().classList.add("no-select"); - row.getElement().classList.remove("tabulator-selectable"); + if (!this.checkFileType(data, this.allowedMimeTypes)) { + row.getElement().classList.add('no-select'); + row.getElement().classList.remove('tabulator-selectable'); } if (this.directoriesOnly && typeof data.mime !== 'undefined') { - row.getElement().classList.add("no-select"); - row.getElement().classList.remove("tabulator-selectable"); + row.getElement().classList.add('no-select'); + row.getElement().classList.remove('tabulator-selectable'); } }, rowSelectionChanged: (data, rows) => { @@ -299,20 +310,35 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } else { this.folderIsSelected = i18n.t('nextcloud-file-picker.load-in-folder'); } - if (!this.directoriesOnly && this.tabulatorTable && this.tabulatorTable.getSelectedRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes)).length > 0) { + if ( + !this.directoriesOnly && + this.tabulatorTable && + this.tabulatorTable + .getSelectedRows() + .filter( + (row) => + row.getData().type != 'directory' && + this.checkFileType(row.getData(), this.allowedMimeTypes) + ).length > 0 + ) { this.selectBtnDisabled = false; } else { this.selectBtnDisabled = true; } - if (this._("#select_all_checkmark")) { - this._("#select_all_checkmark").title = this.checkAllSelected() ? i18n.t('clipboard.select-nothing') : i18n.t('clipboard.select-all'); + if (this._('#select_all_checkmark')) { + this._('#select_all_checkmark').title = this.checkAllSelected() + ? i18n.t('clipboard.select-nothing') + : i18n.t('clipboard.select-all'); } this.requestUpdate(); } }, rowClick: (e, row) => { const data = row.getData(); - if (!row.getElement().classList.contains("no-select") && !this.disableRowClick) { + if ( + !row.getElement().classList.contains('no-select') && + !this.disableRowClick + ) { if (this.directoriesOnly) { // comment out if you want to navigate through folders with double click const data = row.getData(); @@ -320,15 +346,27 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.folderIsSelected = i18n.t('nextcloud-file-picker.load-in-folder'); } else { switch (data.type) { - case "directory": + case 'directory': this.directoryClicked(e, data); break; - case "file": - if (this.tabulatorTable !== null - && this.tabulatorTable.getSelectedRows().length === this.tabulatorTable.getRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes)).length) { - this._("#select_all").checked = true; + case 'file': + if ( + this.tabulatorTable !== null && + this.tabulatorTable.getSelectedRows().length === + this.tabulatorTable + .getRows() + .filter( + (row) => + row.getData().type != 'directory' && + this.checkFileType( + row.getData(), + this.allowedMimeTypes + ) + ).length + ) { + this._('#select_all').checked = true; } else { - this._("#select_all").checked = false; + this._('#select_all').checked = false; } break; } @@ -348,23 +386,35 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { rowAdded: (row) => { // console.log('row added'); if (!this.disableRowClick) { - row.getElement().classList.toggle("addRowAnimation"); + row.getElement().classList.toggle('addRowAnimation'); } }, dataLoaded: () => { if (this.tabulatorTable !== null) { const that = this; - setTimeout(function(){ + setTimeout(function () { if (that._('.tabulator-responsive-collapse-toggle-open')) { - that._a('.tabulator-responsive-collapse-toggle-open').forEach(element => element.addEventListener("click", that.toggleCollapse.bind(that))); + that._a('.tabulator-responsive-collapse-toggle-open').forEach( + (element) => + element.addEventListener( + 'click', + that.toggleCollapse.bind(that) + ) + ); } if (that._('.tabulator-responsive-collapse-toggle-close')) { - that._a('.tabulator-responsive-collapse-toggle-close').forEach(element => element.addEventListener("click", that.toggleCollapse.bind(that))); + that._a('.tabulator-responsive-collapse-toggle-close').forEach( + (element) => + element.addEventListener( + 'click', + that.toggleCollapse.bind(that) + ) + ); } }, 0); } - } + }, }); // Strg + click select mode on desktop @@ -372,7 +422,11 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.tabulatorTable.options.selectableRangeMode = "click"; }*/ - if (typeof this.allowedMimeTypes !== 'undefined' && this.allowedMimeTypes !== '' && !this.directoriesOnly) { + if ( + typeof this.allowedMimeTypes !== 'undefined' && + this.allowedMimeTypes !== '' && + !this.directoriesOnly + ) { this.tabulatorTable.setFilter(this.checkFileType, this.allowedMimeTypes); } // comment this in to show only directories in filesink @@ -402,7 +456,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this._loginState = newLoginState; - if (this.isLoggedIn() && !this._loginCalled ) { + if (this.isLoggedIn() && !this._loginCalled) { this._loginCalled = true; this.loginCallback(); } @@ -418,7 +472,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @returns {boolean} true or false */ isLoggedIn() { - return (this.auth.person !== undefined && this.auth.person !== null); + return this.auth.person !== undefined && this.auth.person !== null; } /** @@ -427,10 +481,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @returns {boolean} true or false */ isLoading() { - if (this._loginStatus === "logged-out") - return false; + if (this._loginStatus === 'logged-out') return false; - return (!this.isLoggedIn() && this.auth.token !== undefined); + return !this.isLoggedIn() && this.auth.token !== undefined; } /** @@ -439,7 +492,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { async checkLocalStorage() { if (!this.isLoggedIn() || !this.auth) { for (let key of Object.keys(localStorage)) { - if (key.includes("nextcloud-webdav-username-") || key.includes("nextcloud-webdav-password-")) { + if ( + key.includes('nextcloud-webdav-username-') || + key.includes('nextcloud-webdav-password-') + ) { localStorage.removeItem(key); } } @@ -447,35 +503,40 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } const publicId = this.auth['person-id']; const token = parseJwt(this.auth.token); - const sessionId = token ? token.sid : ""; - - if (this.storeSession && sessionId - && localStorage.getItem('nextcloud-webdav-username-' + publicId) - && localStorage.getItem('nextcloud-webdav-password-' + publicId) ){ - try { - const userName = await decrypt(sessionId, localStorage.getItem('nextcloud-webdav-username-' + publicId)); - const password = await decrypt(sessionId, localStorage.getItem('nextcloud-webdav-password-' + publicId)); - this.webDavClient = createClient( - this.webDavUrl + '/' + userName, - { - username: userName, - password: password - } - ); + const sessionId = token ? token.sid : ''; + + if ( + this.storeSession && + sessionId && + localStorage.getItem('nextcloud-webdav-username-' + publicId) && + localStorage.getItem('nextcloud-webdav-password-' + publicId) + ) { + try { + const userName = await decrypt( + sessionId, + localStorage.getItem('nextcloud-webdav-username-' + publicId) + ); + const password = await decrypt( + sessionId, + localStorage.getItem('nextcloud-webdav-password-' + publicId) + ); + this.webDavClient = createClient(this.webDavUrl + '/' + userName, { + username: userName, + password: password, + }); - this.userName = userName; + this.userName = userName; - this.isPickerActive = true; - this.loadDirectory(this.directoryPath); - } catch (e) { - localStorage.removeItem('nextcloud-webdav-username-' + publicId); - localStorage.removeItem('nextcloud-webdav-password-' + publicId); - return; - } + this.isPickerActive = true; + this.loadDirectory(this.directoryPath); + } catch (e) { + localStorage.removeItem('nextcloud-webdav-username-' + publicId); + localStorage.removeItem('nextcloud-webdav-password-' + publicId); + return; + } } } - /** * check mime type of row * @@ -483,8 +544,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @param filterParams */ checkFileType(data, filterParams) { - if (filterParams === '') - return true; + if (filterParams === '') return true; if (typeof data.mime === 'undefined') { return true; } @@ -494,7 +554,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { mimeTypes.forEach((str) => { const [mainType, subType] = str.split('/'); - deny = deny && ((mainType !== '*' && mainType !== fileMainType) || (subType !== '*' && subType !== fileSubType)); + deny = + deny && + ((mainType !== '*' && mainType !== fileMainType) || + (subType !== '*' && subType !== fileSubType)); }); return !deny; @@ -506,46 +569,59 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { if (this.webDavClient === null) { this.loading = true; 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"); + 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); } } _a(selector) { - return this.shadowRoot === null ? this.querySelectorAll(selector) : this.shadowRoot.querySelectorAll(selector); + return this.shadowRoot === null + ? this.querySelectorAll(selector) + : this.shadowRoot.querySelectorAll(selector); } async onReceiveWindowMessage(event) { if (this.webDavClient === null) { const data = event.data; - if (data.type === "webapppassword") { + if (data.type === 'webapppassword') { if (this.loginWindow !== null) { this.loginWindow.close(); } // See https://github.com/perry-mitchell/webdav-client/blob/master/API.md#module_WebDAV.createClient this.webDavClient = createClient( - data.webdavUrl || this.webDavUrl + "/" + data.loginName, + data.webdavUrl || this.webDavUrl + '/' + data.loginName, { username: data.loginName, - password: data.token + password: data.token, } ); - - if (this.storeSession && this.isLoggedIn() && this._("#remember-checkbox") && this._("#remember-checkbox").checked) { + if ( + this.storeSession && + this.isLoggedIn() && + this._('#remember-checkbox') && + this._('#remember-checkbox').checked + ) { const publicId = this.auth['person-id']; const token = parseJwt(this.auth.token); - const sessionId = token ? token.sid : ""; + const sessionId = token ? token.sid : ''; if (sessionId) { const encrytedName = await encrypt(sessionId, data.loginName); const encrytedToken = await encrypt(sessionId, data.token); localStorage.setItem('nextcloud-webdav-username-' + publicId, encrytedName); - localStorage.setItem('nextcloud-webdav-password-' + publicId, encrytedToken); + localStorage.setItem( + 'nextcloud-webdav-password-' + publicId, + encrytedToken + ); } } @@ -557,14 +633,14 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { toggleCollapse(e) { const table = this.tabulatorTable; - setTimeout(function() { + setTimeout(function () { table.redraw(); }, 0); } /** - * - * @param {*} data + * + * @param {*} data * @returns reduced list of objects, including users files */ filterUserFilesOnly(data) { @@ -584,13 +660,14 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } /** - * - * @param {*} path + * + * @param {*} path * @returns array including file path and base name */ parseFileAndBaseName(path) { - if (path[0] !== "/") { //TODO verify - path = "/" + path; + if (path[0] !== '/') { + //TODO verify + path = '/' + path; } while (/^.+\/$/.test(path)) { path = path.substr(0, path.length - 1); @@ -601,7 +678,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { let array2 = path.split('/'); for (let i = 0; i < array2.length; i++) { let item2 = array2[i]; - array1.forEach(item1 => { + array1.forEach((item1) => { if (item1 === item2) { array2.shift(); i--; @@ -612,43 +689,65 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { let basename = array2[array2.length - 1]; let filename = '/' + array2.join('/'); - - return [ filename, basename ]; + + return [filename, basename]; } /** - * - * @param {*} response + * + * @param {*} response * @returns list of file objects containing corresponding information */ mapResponseToObject(response) { let results = []; - response.forEach(item => { - const [ filePath, baseName ] = this.parseFileAndBaseName(item.href); + response.forEach((item) => { + const [filePath, baseName] = this.parseFileAndBaseName(item.href); const prop = item.propstat.prop; let etag = typeof prop.getetag === 'string' ? prop.getetag.replace(/"/g, '') : null; let sizeVal = prop.getcontentlength ? prop.getcontentlength : '0'; - let fileType = prop.resourcetype && typeof prop.resourcetype === 'object' && typeof prop.resourcetype.collection !== 'undefined' ? 'directory' : 'file'; - + let fileType = + prop.resourcetype && + typeof prop.resourcetype === 'object' && + typeof prop.resourcetype.collection !== 'undefined' + ? 'directory' + : 'file'; + let mimeType; if (fileType === 'file') { - mimeType = prop.getcontenttype && typeof prop.getcontenttype === 'string' ? prop.getcontenttype.split(';')[0] : ''; - } - - let propsObject = { getetag: etag, getlastmodified: prop.getlastmodified, getcontentlength: sizeVal, - permissions: prop.permissions, resourcetype: fileType, getcontenttype: prop.getcontenttype }; - - let statObject = { basename: baseName, etag: etag, filename: filePath, lastmod: prop.getlastmodified, - mime: mimeType, props: propsObject, size: parseInt(sizeVal, 10), type: fileType }; + mimeType = + prop.getcontenttype && typeof prop.getcontenttype === 'string' + ? prop.getcontenttype.split(';')[0] + : ''; + } + + let propsObject = { + getetag: etag, + getlastmodified: prop.getlastmodified, + getcontentlength: sizeVal, + permissions: prop.permissions, + resourcetype: fileType, + getcontenttype: prop.getcontenttype, + }; + + let statObject = { + basename: baseName, + etag: etag, + filename: filePath, + lastmod: prop.getlastmodified, + mime: mimeType, + props: propsObject, + size: parseInt(sizeVal, 10), + type: fileType, + }; results.push(statObject); }); return results; } - + /** * Loads the favorites from WebDAV * @@ -661,88 +760,117 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.directoryPath = ''; } - console.log("load nextcloud favorites"); + console.log('load nextcloud favorites'); this.selectAllButton = true; this.loading = true; - this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', {name: this.nextcloudName}); + this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', { + name: this.nextcloudName, + }); this.lastDirectoryPath = this.directoryPath; this.directoryPath = ''; this.isInRecent = false; this.isInFilteredRecent = false; this.isInFavorites = true; - + if (this.webDavClient === null) { // client is broken reload try to reset & reconnect this.tabulatorTable.clearData(); this.webDavClient = null; - let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button" + let reloadButton = html`${i18n.t( + 'nextcloud-file-picker.something-went-wrong' + )} <button class="button" title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" - @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`; + @click="${async () => { + this.openFilePicker(); + }}"><dbp-icon name="reload"></button>`; this.loading = false; this.statusText = reloadButton; } //see https://github.com/perry-mitchell/webdav-client#customRequest this.webDavClient - .customRequest('/', {method: 'REPORT', responseType: "text/xml", details: true, data: "<?xml version=\"1.0\"?>" + - " <oc:filter-files xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">" + - " <oc:filter-rules>" + - " <oc:favorite>1</oc:favorite>" + - " </oc:filter-rules>" + - " <d:prop>" + - " <d:getlastmodified />" + - " <d:resourcetype />" + - " <d:getcontenttype />" + - " <d:getcontentlength />" + - " <d:getetag />" + - " <oc:permissions />" + - " </d:prop>" + - " </oc:filter-files>" - }) - .then(contents => { - parseXML(contents.data).then(davResp => { + .customRequest('/', { + method: 'REPORT', + responseType: 'text/xml', + details: true, + data: + '<?xml version="1.0"?>' + + ' <oc:filter-files xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">' + + ' <oc:filter-rules>' + + ' <oc:favorite>1</oc:favorite>' + + ' </oc:filter-rules>' + + ' <d:prop>' + + ' <d:getlastmodified />' + + ' <d:resourcetype />' + + ' <d:getcontenttype />' + + ' <d:getcontentlength />' + + ' <d:getetag />' + + ' <oc:permissions />' + + ' </d:prop>' + + ' </oc:filter-files>', + }) + .then((contents) => { + parseXML(contents.data).then((davResp) => { // console.log("-contents.data-----", davResp); let dataObject = this.mapResponseToObject(davResp.multistatus.response); this.loading = false; - this.statusText = ""; + this.statusText = ''; this.tabulatorTable.setData(dataObject); - if (this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span")) { - this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span").innerText = i18n.t('nextcloud-file-picker.no-favorites', { name: this.nextcloudName }); + if ( + this._('#directory-content-table').querySelector( + 'div.tabulator-tableHolder > div.tabulator-placeholder > span' + ) + ) { + this._('#directory-content-table').querySelector( + 'div.tabulator-tableHolder > div.tabulator-placeholder > span' + ).innerText = i18n.t('nextcloud-file-picker.no-favorites', { + name: this.nextcloudName, + }); } this.isPickerActive = true; - this._(".nextcloud-content").scrollTop = 0; - this._("#download-button").setAttribute("disabled", "true"); - + this._('.nextcloud-content').scrollTop = 0; + this._('#download-button').setAttribute('disabled', 'true'); }); - }).catch(error => { //TODO verify error catching + }) + .catch((error) => { + //TODO verify error catching console.error(error.message); // on Error: try to reload with home directory - if (this.webDavClient !== null && error.message.search("401") === -1) { - console.log("error in load directory"); - this.directoryPath = ""; - this.loadDirectory(""); - } - else { + if (this.webDavClient !== null && error.message.search('401') === -1) { + console.log('error in load directory'); + this.directoryPath = ''; + this.loadDirectory(''); + } else { this.loading = false; - this.statusText = html`<span class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`; + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} + </span> + `; this.isPickerActive = false; this.tabulatorTable.clearData(); this.webDavClient = null; - let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button" - title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" - @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`; + let reloadButton = html`${i18n.t( + 'nextcloud-file-picker.something-went-wrong' + )} <button class="button" + title="${i18n.t( + 'nextcloud-file-picker.refresh-nextcloud-file-picker' + )}" + @click="${async () => { + this.openFilePicker(); + }}"><dbp-icon name="reload"></button>`; this.loading = false; this.statusText = reloadButton; } this.isInFavorites = false; - }); + }); } - /** + /** * Loads recent files and folders from WebDAV * */ @@ -754,10 +882,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.directoryPath = ''; } - console.log("load recent files"); + console.log('load recent files'); this.selectAllButton = true; this.loading = true; - this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', {name: this.nextcloudName}); + this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', { + name: this.nextcloudName, + }); this.lastDirectoryPath = this.directoryPath; this.directoryPath = ''; this.isInFavorites = false; @@ -772,107 +902,135 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { // client is broken reload try to reset & reconnect this.tabulatorTable.clearData(); this.webDavClient = null; - let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button" + let reloadButton = html`${i18n.t( + 'nextcloud-file-picker.something-went-wrong' + )} <button class="button" title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" - @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`; + @click="${async () => { + this.openFilePicker(); + }}"><dbp-icon name="reload"></button>`; this.loading = false; this.statusText = reloadButton; } //see https://github.com/perry-mitchell/webdav-client#customRequest this.webDavClient - .customRequest('../..', { method: 'SEARCH', responseType: "text/xml", headers: { 'Content-Type': "text/xml" }, details: true, data: "<?xml version=\"1.0\" encoding='UTF-8'?>" + - " <d:searchrequest xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">" + - " <d:basicsearch>" + - " <d:select>" + - " <d:prop>" + - " <d:getlastmodified />" + - " <d:resourcetype />" + - " <d:getcontenttype />" + - " <d:getcontentlength />" + - " <d:getetag />" + - " <oc:permissions />" + - " <oc:size/>"+ - " <oc:owner-id/>" + - " <oc:owner-display-name/>" + - " </d:prop>" + - " </d:select>" + - " <d:from>" + - " <d:scope>" + - " <d:href>/files/" + this.userName + "/</d:href>" + - " <d:depth>infinity</d:depth>" + - " </d:scope>" + - " </d:from>" + - " <d:where> " + - " <d:gte>" + - " <d:prop>" + - " <d:getlastmodified/>" + - " </d:prop>" + - " <d:literal>" + searchDate + "</d:literal>" + - " </d:gte>" + - " </d:where>" + - " <d:orderby>" + - " <d:order>" + - " <d:prop>" + - " <d:getlastmodified/>" + - " </d:prop>" + - " <d:descending/>" + - " </d:order>" + - " </d:orderby>" + - " <d:limit>"+ - " <d:nresults>15</d:nresults>" + - " </d:limit>"+ - " </d:basicsearch>" + - " </d:searchrequest>" + .customRequest('../..', { + method: 'SEARCH', + responseType: 'text/xml', + headers: {'Content-Type': 'text/xml'}, + details: true, + data: + '<?xml version="1.0" encoding=\'UTF-8\'?>' + + ' <d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">' + + ' <d:basicsearch>' + + ' <d:select>' + + ' <d:prop>' + + ' <d:getlastmodified />' + + ' <d:resourcetype />' + + ' <d:getcontenttype />' + + ' <d:getcontentlength />' + + ' <d:getetag />' + + ' <oc:permissions />' + + ' <oc:size/>' + + ' <oc:owner-id/>' + + ' <oc:owner-display-name/>' + + ' </d:prop>' + + ' </d:select>' + + ' <d:from>' + + ' <d:scope>' + + ' <d:href>/files/' + + this.userName + + '/</d:href>' + + ' <d:depth>infinity</d:depth>' + + ' </d:scope>' + + ' </d:from>' + + ' <d:where> ' + + ' <d:gte>' + + ' <d:prop>' + + ' <d:getlastmodified/>' + + ' </d:prop>' + + ' <d:literal>' + + searchDate + + '</d:literal>' + + ' </d:gte>' + + ' </d:where>' + + ' <d:orderby>' + + ' <d:order>' + + ' <d:prop>' + + ' <d:getlastmodified/>' + + ' </d:prop>' + + ' <d:descending/>' + + ' </d:order>' + + ' </d:orderby>' + + ' <d:limit>' + + ' <d:nresults>15</d:nresults>' + + ' </d:limit>' + + ' </d:basicsearch>' + + ' </d:searchrequest>', }) - .then(contents => { - parseXML(contents.data).then(davResp => { + .then((contents) => { + parseXML(contents.data).then((davResp) => { // console.log('davResp', davResp); let dataObject = this.mapResponseToObject(davResp.multistatus.response); // console.log("-contents.data-----", dataObject); this.loading = false; - this.statusText = ""; + this.statusText = ''; this.tabulatorTable.setData(dataObject); - this.tabulatorTable.setSort([ - {column: "lastmod", dir: "desc"} - ]); - - if (this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span")) { - this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span").innerText = i18n.t('nextcloud-file-picker.no-recent-files'); + this.tabulatorTable.setSort([{column: 'lastmod', dir: 'desc'}]); + + if ( + this._('#directory-content-table').querySelector( + 'div.tabulator-tableHolder > div.tabulator-placeholder > span' + ) + ) { + this._('#directory-content-table').querySelector( + 'div.tabulator-tableHolder > div.tabulator-placeholder > span' + ).innerText = i18n.t('nextcloud-file-picker.no-recent-files'); } this.isPickerActive = true; - this._(".nextcloud-content").scrollTop = 0; - this._("#download-button").setAttribute("disabled", "true"); + this._('.nextcloud-content').scrollTop = 0; + this._('#download-button').setAttribute('disabled', 'true'); }); - }).catch(error => { + }) + .catch((error) => { console.error(error.message); // on Error: try to reload with home directory - if (this.webDavClient !== null && error.message.search("401") === -1) { - console.log("error in load directory"); - this.directoryPath = ""; - this.loadDirectory(""); - } - else { + if (this.webDavClient !== null && error.message.search('401') === -1) { + console.log('error in load directory'); + this.directoryPath = ''; + this.loadDirectory(''); + } else { this.loading = false; - this.statusText = html`<span class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`; + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} + </span> + `; this.isPickerActive = false; this.tabulatorTable.clearData(); this.webDavClient = null; - let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button" - title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" - @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`; + let reloadButton = html`${i18n.t( + 'nextcloud-file-picker.something-went-wrong' + )} <button class="button" + title="${i18n.t( + 'nextcloud-file-picker.refresh-nextcloud-file-picker' + )}" + @click="${async () => { + this.openFilePicker(); + }}"><dbp-icon name="reload"></button>`; this.loading = false; this.statusText = reloadButton; } this.isInRecent = false; - }); + }); } - /** + /** * Loads recent files and folders from WebDAV * */ @@ -884,10 +1042,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.directoryPath = ''; } - console.log("load only my recent files"); + console.log('load only my recent files'); this.selectAllButton = true; this.loading = true; - this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', {name: this.nextcloudName}); + this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', { + name: this.nextcloudName, + }); this.lastDirectoryPath = this.directoryPath; this.directoryPath = ''; this.isInFavorites = false; @@ -902,61 +1062,75 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { // client is broken reload try to reset & reconnect this.tabulatorTable.clearData(); this.webDavClient = null; - let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button" + let reloadButton = html`${i18n.t( + 'nextcloud-file-picker.something-went-wrong' + )} <button class="button" title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" - @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`; + @click="${async () => { + this.openFilePicker(); + }}"><dbp-icon name="reload"></button>`; this.loading = false; this.statusText = reloadButton; } //see https://github.com/perry-mitchell/webdav-client#customRequest this.webDavClient - .customRequest('../..', { method: 'SEARCH', responseType: "text/xml", headers: { 'Content-Type': "text/xml" }, details: true, data: "<?xml version=\"1.0\" encoding='UTF-8'?>" + - " <d:searchrequest xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">" + - " <d:basicsearch>" + - " <d:select>" + - " <d:prop>" + - " <d:getlastmodified />" + - " <d:resourcetype />" + - " <d:getcontenttype />" + - " <d:getcontentlength />" + - " <d:getetag />" + - " <oc:permissions />" + - " <oc:size/>"+ - " <oc:owner-id/>" + - " <oc:owner-display-name/>" + - " </d:prop>" + - " </d:select>" + - " <d:from>" + - " <d:scope>" + - " <d:href>/files/" + this.userName + "/</d:href>" + - " <d:depth>infinity</d:depth>" + - " </d:scope>" + - " </d:from>" + - " <d:where> " + - " <d:gte>" + - " <d:prop>" + - " <d:getlastmodified/>" + - " </d:prop>" + - " <d:literal>" + searchDate + "</d:literal>" + - " </d:gte>" + - " </d:where>" + - " <d:orderby>" + - " <d:order>" + - " <d:prop>" + - " <d:getlastmodified/>" + - " </d:prop>" + - " <d:descending/>" + - " </d:order>" + - " </d:orderby>" + - " <d:limit>"+ - " <d:nresults>15</d:nresults>" + - " </d:limit>"+ - " </d:basicsearch>" + - " </d:searchrequest>" + .customRequest('../..', { + method: 'SEARCH', + responseType: 'text/xml', + headers: {'Content-Type': 'text/xml'}, + details: true, + data: + '<?xml version="1.0" encoding=\'UTF-8\'?>' + + ' <d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">' + + ' <d:basicsearch>' + + ' <d:select>' + + ' <d:prop>' + + ' <d:getlastmodified />' + + ' <d:resourcetype />' + + ' <d:getcontenttype />' + + ' <d:getcontentlength />' + + ' <d:getetag />' + + ' <oc:permissions />' + + ' <oc:size/>' + + ' <oc:owner-id/>' + + ' <oc:owner-display-name/>' + + ' </d:prop>' + + ' </d:select>' + + ' <d:from>' + + ' <d:scope>' + + ' <d:href>/files/' + + this.userName + + '/</d:href>' + + ' <d:depth>infinity</d:depth>' + + ' </d:scope>' + + ' </d:from>' + + ' <d:where> ' + + ' <d:gte>' + + ' <d:prop>' + + ' <d:getlastmodified/>' + + ' </d:prop>' + + ' <d:literal>' + + searchDate + + '</d:literal>' + + ' </d:gte>' + + ' </d:where>' + + ' <d:orderby>' + + ' <d:order>' + + ' <d:prop>' + + ' <d:getlastmodified/>' + + ' </d:prop>' + + ' <d:descending/>' + + ' </d:order>' + + ' </d:orderby>' + + ' <d:limit>' + + ' <d:nresults>15</d:nresults>' + + ' </d:limit>' + + ' </d:basicsearch>' + + ' </d:searchrequest>', }) - .then(contents => { - parseXML(contents.data).then(davResp => { + .then((contents) => { + parseXML(contents.data).then((davResp) => { // console.log('davResp', davResp); let dataObject = this.mapResponseToObject(davResp.multistatus.response); // console.log("-contents.data-----", dataObject); @@ -965,44 +1139,58 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { dataObject = this.filterUserFilesOnly(dataObject); this.loading = false; - this.statusText = ""; + this.statusText = ''; this.tabulatorTable.setData(dataObject); - this.tabulatorTable.setSort([ - {column: "lastmod", dir: "desc"} - ]); - - if (this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span")) { - this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span").innerText = i18n.t('nextcloud-file-picker.no-recent-files'); + this.tabulatorTable.setSort([{column: 'lastmod', dir: 'desc'}]); + + if ( + this._('#directory-content-table').querySelector( + 'div.tabulator-tableHolder > div.tabulator-placeholder > span' + ) + ) { + this._('#directory-content-table').querySelector( + 'div.tabulator-tableHolder > div.tabulator-placeholder > span' + ).innerText = i18n.t('nextcloud-file-picker.no-recent-files'); } this.isPickerActive = true; - this._(".nextcloud-content").scrollTop = 0; - this._("#download-button").setAttribute("disabled", "true"); + this._('.nextcloud-content').scrollTop = 0; + this._('#download-button').setAttribute('disabled', 'true'); }); - }).catch(error => { + }) + .catch((error) => { console.error(error.message); // on Error: try to reload with home directory - if (this.webDavClient !== null && error.message.search("401") === -1) { - console.log("error in load directory"); - this.directoryPath = ""; - this.loadDirectory(""); - } - else { + if (this.webDavClient !== null && error.message.search('401') === -1) { + console.log('error in load directory'); + this.directoryPath = ''; + this.loadDirectory(''); + } else { this.loading = false; - this.statusText = html`<span class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`; + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} + </span> + `; this.isPickerActive = false; this.tabulatorTable.clearData(); this.webDavClient = null; - let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button" - title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" - @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`; + let reloadButton = html`${i18n.t( + 'nextcloud-file-picker.something-went-wrong' + )} <button class="button" + title="${i18n.t( + 'nextcloud-file-picker.refresh-nextcloud-file-picker' + )}" + @click="${async () => { + this.openFilePicker(); + }}"><dbp-icon name="reload"></button>`; this.loading = false; this.statusText = reloadButton; } this.isInFilteredRecent = false; - }); + }); } /** @@ -1012,7 +1200,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { */ loadDirectory(path) { this.hideAdditionalMenu(); - + const i18n = this._i18n; if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) { this.directoryPath = ''; @@ -1023,93 +1211,120 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.disableRowClick = false; this.loading = true; - this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', {name: this.nextcloudName}); + this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', { + name: this.nextcloudName, + }); this.lastDirectoryPath = this.directoryPath; this.directoryPath = path; - if (this._("#select_all")) - this._("#select_all").checked = false; + if (this._('#select_all')) this._('#select_all').checked = false; // see https://github.com/perry-mitchell/webdav-client#getdirectorycontents if (this.webDavClient === null) { // client is broken reload try to reset & reconnect this.tabulatorTable.clearData(); this.webDavClient = null; - let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} - <button class="button" + let reloadButton = html` + ${i18n.t('nextcloud-file-picker.something-went-wrong')} + <button + class="button" title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" @click="${async () => { this.openFilePicker(); }}"> - <dbp-icon name="reload"></dbp-icon> - </button>`; + <dbp-icon name="reload"></dbp-icon> + </button> + `; this.loading = false; this.statusText = reloadButton; } this.webDavClient .getDirectoryContents(path, { - details: true, data: "<?xml version=\"1.0\"?>" + - "<d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\" xmlns:ocs=\"http://open-collaboration-services.org/ns\">" + - " <d:prop>" + - " <d:getlastmodified />" + - " <d:resourcetype />" + - " <d:getcontenttype />" + - " <d:getcontentlength />" + - " <d:getetag />" + - " <oc:permissions />" + - " <nc:acl-list>" + - " <nc:acl>" + - " <nc:acl-permissions />" + - " </nc:acl>" + - " </nc:acl-list>" + - " </d:prop>" + - "</d:propfind>" + details: true, + data: + '<?xml version="1.0"?>' + + '<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns" xmlns:ocs="http://open-collaboration-services.org/ns">' + + ' <d:prop>' + + ' <d:getlastmodified />' + + ' <d:resourcetype />' + + ' <d:getcontenttype />' + + ' <d:getcontentlength />' + + ' <d:getetag />' + + ' <oc:permissions />' + + ' <nc:acl-list>' + + ' <nc:acl>' + + ' <nc:acl-permissions />' + + ' </nc:acl>' + + ' </nc:acl-list>' + + ' </d:prop>' + + '</d:propfind>', }) - .then(contents => { + .then((contents) => { this.loading = false; - this.statusText = ""; + this.statusText = ''; this.tabulatorTable.setData(contents.data); this.isPickerActive = true; this.isInFavorites = false; this.isInRecent = false; this.isInFilteredRecent = false; - this._(".nextcloud-content").scrollTop = 0; - if (!this.activeDirectoryRights.includes("CK") && !this.activeDirectoryRights.includes("NV")) { - this._("#download-button").setAttribute("disabled", "true"); + this._('.nextcloud-content').scrollTop = 0; + if ( + !this.activeDirectoryRights.includes('CK') && + !this.activeDirectoryRights.includes('NV') + ) { + this._('#download-button').setAttribute('disabled', 'true'); } else { - this._("#download-button").removeAttribute("disabled"); + this._('#download-button').removeAttribute('disabled'); } - if (this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span")) { - this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span").innerText = this.directoriesOnly ? i18n.t('nextcloud-file-picker.no-data') : i18n.t('nextcloud-file-picker.no-data-type'); + if ( + this._('#directory-content-table').querySelector( + 'div.tabulator-tableHolder > div.tabulator-placeholder > span' + ) + ) { + this._('#directory-content-table').querySelector( + 'div.tabulator-tableHolder > div.tabulator-placeholder > span' + ).innerText = this.directoriesOnly + ? i18n.t('nextcloud-file-picker.no-data') + : i18n.t('nextcloud-file-picker.no-data-type'); } + }) + .catch((error) => { + console.error(error.message); - }).catch(error => { - console.error(error.message); - - // on Error: try to reload with home directory - if ((path !== "/" && path !== "") && this.webDavClient !== null && error.message.search("401") === -1) { - console.log("error in load directory"); - this.directoryPath = ""; - this.loadDirectory(""); - - } else { - this.loading = false; - this.statusText = html`<span - class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`; - this.isPickerActive = false; - this.tabulatorTable.clearData(); - this.webDavClient = null; - let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} - <button class="button" - title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" - @click="${async () => { - this.openFilePicker(); - }}"> - <dbp-icon name="reload"></dbp-icon> - </button>`; - this.loading = false; - this.statusText = reloadButton; - } - }); + // on Error: try to reload with home directory + if ( + path !== '/' && + path !== '' && + this.webDavClient !== null && + error.message.search('401') === -1 + ) { + console.log('error in load directory'); + this.directoryPath = ''; + this.loadDirectory(''); + } else { + this.loading = false; + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} + </span> + `; + this.isPickerActive = false; + this.tabulatorTable.clearData(); + this.webDavClient = null; + let reloadButton = html` + ${i18n.t('nextcloud-file-picker.something-went-wrong')} + <button + class="button" + title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" + @click="${async () => { + this.openFilePicker(); + }}"> + <dbp-icon name="reload"></dbp-icon> + </button> + `; + this.loading = false; + this.statusText = reloadButton; + } + }); } /** @@ -1122,8 +1337,11 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { // save rights of clicked directory if (typeof file.props !== 'undefined') { this.activeDirectoryRights = file.props.permissions; - if (typeof file.props['acl-list'] !== "undefined" && - typeof file.props['acl-list']['acl']['acl-permissions'] !== "undefined" && file.props['acl-list']['acl']['acl-permissions']) { + if ( + typeof file.props['acl-list'] !== 'undefined' && + typeof file.props['acl-list']['acl']['acl-permissions'] !== 'undefined' && + file.props['acl-list']['acl']['acl-permissions'] + ) { this.activeDirectoryACL = file.props['acl-list']['acl']['acl-permissions']; } else { this.activeDirectoryACL = ''; @@ -1144,18 +1362,23 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { files.forEach((fileData) => this.downloadFile(fileData, files.length)); this.tabulatorTable.deselectRow(); - if (this._("#select_all")) { - this._("#select_all").checked = false; - } - const data = {"count": files.length}; - const event = new CustomEvent("dbp-nextcloud-file-picker-number-files", - {"detail": data, bubbles: true, composed: true}); + if (this._('#select_all')) { + this._('#select_all').checked = false; + } + const data = {count: files.length}; + const event = new CustomEvent('dbp-nextcloud-file-picker-number-files', { + detail: data, + bubbles: true, + composed: true, + }); this.dispatchEvent(event); if (files.length > 0) { - this.sendSetPropertyEvent( - 'analytics-event', - {category: 'FileHandlingNextcloud', action: 'DownloadFiles', name: files.length}); + this.sendSetPropertyEvent('analytics-event', { + category: 'FileHandlingNextcloud', + action: 'DownloadFiles', + name: files.length, + }); } } @@ -1166,30 +1389,36 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @param maxUpload */ downloadFile(fileData, maxUpload) { - const i18n = this._i18n; this.loading = true; - this.statusText = "Loading " + fileData.filename + "..."; + this.statusText = 'Loading ' + fileData.filename + '...'; // https://github.com/perry-mitchell/webdav-client#getfilecontents this.webDavClient .getFileContents(fileData.filename) - .then(contents => { + .then((contents) => { // create file to send via event const file = new File([contents], fileData.basename, {type: fileData.mime}); // send event - const data = {"file": file, "data": fileData, "maxUpload": maxUpload}; - const event = new CustomEvent("dbp-nextcloud-file-picker-file-downloaded", - {"detail": data, bubbles: true, composed: true}); + const data = {file: file, data: fileData, maxUpload: maxUpload}; + const event = new CustomEvent('dbp-nextcloud-file-picker-file-downloaded', { + detail: data, + bubbles: true, + composed: true, + }); this.dispatchEvent(event); this.loading = false; - this.statusText = ""; - }).catch(error => { - console.error(error.message); - this.loading = false; - this.statusText = html`<span - class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`; - }); + this.statusText = ''; + }) + .catch((error) => { + console.error(error.message); + this.loading = false; + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} + </span> + `; + }); } /** @@ -1201,13 +1430,19 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { const i18n = this._i18n; if (this.isInFavorites) { - this.statusText = html`<span class="error"> ${ i18n.t('nextcloud-file-picker.error-save-to-favorites') } </span>`; + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.error-save-to-favorites')} + </span> + `; return; } else if (this.isInRecent || this.isInFilteredRecent) { - this.statusText = html`<span class="error"> ${ i18n.t('nextcloud-file-picker.error-save-to-recent') } </span>`; + this.statusText = html` + <span class="error">${i18n.t('nextcloud-file-picker.error-save-to-recent')}</span> + `; return; } - + this.tabulatorTable.deselectRow(); let path; @@ -1219,8 +1454,11 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.loading = true; this.statusText = i18n.t('nextcloud-file-picker.upload-to', {path: path}); - const event = new CustomEvent("dbp-nextcloud-file-picker-file-uploaded", - {"detail": path, bubbles: true, composed: true}); + const event = new CustomEvent('dbp-nextcloud-file-picker-file-uploaded', { + detail: path, + bubbles: true, + composed: true, + }); this.dispatchEvent(event); } @@ -1240,9 +1478,11 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.uploadFile(directory); if (files.length > 0) { - this.sendSetPropertyEvent( - 'analytics-event', - {category: 'FileHandlingNextcloud', action: 'UploadFiles', name: files.length}); + this.sendSetPropertyEvent('analytics-event', { + category: 'FileHandlingNextcloud', + action: 'UploadFiles', + name: files.length, + }); } } @@ -1259,13 +1499,13 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.forAll = false; this.loading = false; this.statusText = i18n.t('nextcloud-file-picker.abort-message'); - this._("#replace_mode_all").checked = false; + this._('#replace_mode_all').checked = false; return; } if (this.fileList.length !== 0) { let file = this.fileList[0]; this.replaceFilename = file.name; - let path = directory + "/" + file.name; + let path = directory + '/' + file.name; // https://github.com/perry-mitchell/webdav-client#putfilecontents let that = this; this.loading = true; @@ -1274,17 +1514,20 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { await this.webDavClient .putFileContents(path, file, { contentLength: file.size, - overwrite: false, onUploadProgress: progress => { + overwrite: false, + onUploadProgress: (progress) => { /* console.log(`Uploaded ${progress.loaded} bytes of ${progress.total}`);*/ - } - }).then(function () { + }, + }) + .then(function () { that.uploadCount += 1; that.fileList.shift(); that.uploadFile(directory); - }).catch(error => { - if (error.message.search("412") !== -1 || error.message.search("403") !== -1) { + }) + .catch((error) => { + if (error.message.search('412') !== -1 || error.message.search('403') !== -1) { this.generatedFilename = this.getNextFilename(); - this._("#replace-filename").value = this.generatedFilename; + this._('#replace-filename').value = this.generatedFilename; if (this.forAll) { this.uploadFileObject = file; this.uploadFileDirectory = directory; @@ -1300,17 +1543,19 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } else { this.loadDirectory(this.directoryPath); this.loading = false; - this.statusText = ""; - this._("#replace_mode_all").checked = false; + this.statusText = ''; + this._('#replace_mode_all').checked = false; this.forAll = false; this.customFilename = ''; - const event = new CustomEvent("dbp-nextcloud-file-picker-file-uploaded-finished", - {bubbles: true, composed: true, detail: this.uploadCount}); + const event = new CustomEvent('dbp-nextcloud-file-picker-file-uploaded-finished', { + bubbles: true, + composed: true, + detail: this.uploadCount, + }); this.uploadCount = 0; this.abortUpload = false; this.abortUploadButton = false; this.dispatchEvent(event); - } } @@ -1326,28 +1571,28 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.forAll = false; this.loading = false; this.statusText = i18n.t('nextcloud-file-picker.abort-message'); - this._("#replace_mode_all").checked = false; + this._('#replace_mode_all').checked = false; return; } - let path = ""; + let path = ''; let overwrite = false; let file = this.uploadFileObject; let directory = this.uploadFileDirectory; - if (this._("input[name='replacement']:checked").value === "ignore") { - MicroModal.close(this._("#replace-modal")); - this.forAll ? this.fileList = [] : this.fileList.shift(); + if (this._("input[name='replacement']:checked").value === 'ignore') { + MicroModal.close(this._('#replace-modal')); + this.forAll ? (this.fileList = []) : this.fileList.shift(); this.uploadFile(directory); return true; - } else if (this._("input[name='replacement']:checked").value === "new-name") { - if (this.generatedFilename !== this._("#replace-filename").value) { - this.customFilename = this._("#replace-filename").value; + } else if (this._("input[name='replacement']:checked").value === 'new-name') { + if (this.generatedFilename !== this._('#replace-filename').value) { + this.customFilename = this._('#replace-filename').value; } - path = directory + "/" + this._("#replace-filename").value; - MicroModal.close(this._("#replace-modal")); - this.replaceFilename = this._("#replace-filename").value; + path = directory + '/' + this._('#replace-filename').value; + MicroModal.close(this._('#replace-modal')); + this.replaceFilename = this._('#replace-filename').value; } else { - path = directory + "/" + this.uploadFileObject.name; + path = directory + '/' + this.uploadFileObject.name; overwrite = true; } @@ -1360,19 +1605,22 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { await this.webDavClient .putFileContents(path, file, { contentLength: file.size, - overwrite: overwrite, onUploadProgress: progress => { + overwrite: overwrite, + onUploadProgress: (progress) => { /*console.log(`Uploaded ${progress.loaded} bytes of ${progress.total}`);*/ - } - }).then(content => { - MicroModal.close(this._("#replace-modal")); + }, + }) + .then((content) => { + MicroModal.close(this._('#replace-modal')); this.uploadCount += 1; that.fileList.shift(); that.uploadFile(directory); - }).catch(error => { - if (error.message.search("412") !== -1) { - MicroModal.close(that._("#replace-modal")); + }) + .catch((error) => { + if (error.message.search('412') !== -1) { + MicroModal.close(that._('#replace-modal')); this.generatedFilename = this.getNextFilename(); - this._("#replace-filename").value = this.generatedFilename; + this._('#replace-filename').value = this.generatedFilename; if (this.forAll) { this.uploadFileObject = file; this.uploadFileDirectory = directory; @@ -1400,15 +1648,14 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @returns {number} */ checkRights(file) { - // nextcloud permissions let file_perm = 0; let active_directory_perm = this.activeDirectoryRights; - let rows = this.tabulatorTable.searchRows("basename", "=", this.replaceFilename); + let rows = this.tabulatorTable.searchRows('basename', '=', this.replaceFilename); if (typeof rows[0] !== 'undefined' && rows[0]) { file_perm = rows[0].getData().props.permissions; } else { - file_perm = ""; + file_perm = ''; } /* ACL permissions: If ACL > permssions comment this in @@ -1443,23 +1690,22 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { */ // all allowed - if (active_directory_perm.includes("CK") && file_perm.includes("NV")) { + if (active_directory_perm.includes('CK') && file_perm.includes('NV')) { return -1; } // read only file but you can write to directory = only create and no edit - if (active_directory_perm.includes("CK") && !file_perm.includes("NV")) { + if (active_directory_perm.includes('CK') && !file_perm.includes('NV')) { return 1; } // only edit and no create - if (!active_directory_perm.includes("CK") && file_perm.includes("NV")) { + if (!active_directory_perm.includes('CK') && file_perm.includes('NV')) { return 2; } // read only directory and read only file return 0; - } /** @@ -1483,37 +1729,37 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { else if (rights === 1) { this.loading = false; this.statusText = i18n.t('nextcloud-file-picker.onlycreate'); - this._("#replace-replace").setAttribute("disabled", "true"); - this._("#replace-new-name").removeAttribute("disabled"); - this._("#replace-replace").checked = false; - this._("#replace-new-name").checked = true; + this._('#replace-replace').setAttribute('disabled', 'true'); + this._('#replace-new-name').removeAttribute('disabled'); + this._('#replace-replace').checked = false; + this._('#replace-new-name').checked = true; this.setInputFieldVisibility(); - this._("#replace-new-name").focus(); + this._('#replace-new-name').focus(); } // only edit and no create else if (rights === 2) { this.loading = false; this.statusText = i18n.t('nextcloud-file-picker.onlyedit'); - this._("#replace-new-name").setAttribute("disabled", "true"); - this._("#replace-replace").removeAttribute("disabled"); - this._("#replace-new-name").checked = false; - this._("#replace-replace").checked = true; + this._('#replace-new-name').setAttribute('disabled', 'true'); + this._('#replace-replace').removeAttribute('disabled'); + this._('#replace-new-name').checked = false; + this._('#replace-replace').checked = true; this.setInputFieldVisibility(); - this._("#replace-replace").focus(); + this._('#replace-replace').focus(); } // all allowed else { - this._("#replace-new-name").removeAttribute("disabled"); - this._("#replace-replace").removeAttribute("disabled"); - this._("#replace-replace").checked = false; - this._("#replace-new-name").checked = true; + this._('#replace-new-name').removeAttribute('disabled'); + this._('#replace-replace').removeAttribute('disabled'); + this._('#replace-replace').checked = false; + this._('#replace-new-name').checked = true; this.setInputFieldVisibility(); - this._("#replace-new-name").focus(); + this._('#replace-new-name').focus(); } MicroModal.show(this._('#replace-modal'), { disableScroll: true, - onClose: modal => { - this.statusText = ""; + onClose: (modal) => { + this.statusText = ''; this.loading = false; }, }); @@ -1523,8 +1769,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { if (this.tabulatorTable) { this.tabulatorTable.deselectRow(); } - if (this._("#select_all")) { - this._("#select_all").checked = false; + if (this._('#select_all')) { + this._('#select_all').checked = false; } MicroModal.close(this._('#modal-picker')); } @@ -1535,12 +1781,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @returns {string} The next filename */ getNextFilename() { - let nextFilename = ""; + let nextFilename = ''; let splitFilename; if (this.forAll && this.customFilename !== '') { - splitFilename = this.customFilename.split("."); + splitFilename = this.customFilename.split('.'); } else { - splitFilename = this.replaceFilename.split("."); + splitFilename = this.replaceFilename.split('.'); } let splitBracket = splitFilename[0].split('('); @@ -1549,16 +1795,16 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { if (numberString.length > 1 && !isNaN(parseInt(numberString[0]))) { let number = parseInt(numberString[0]); this.fileNameCounter = number + 1; - nextFilename = splitBracket[0] + "(" + this.fileNameCounter + ")"; + nextFilename = splitBracket[0] + '(' + this.fileNameCounter + ')'; } else { - nextFilename = splitFilename[0] + "(" + this.fileNameCounter + ")"; + nextFilename = splitFilename[0] + '(' + this.fileNameCounter + ')'; } } else { - nextFilename = splitFilename[0] + "(" + this.fileNameCounter + ")"; + nextFilename = splitFilename[0] + '(' + this.fileNameCounter + ')'; } if (splitFilename.length > 1) { for (let i = 1; i < splitFilename.length; i++) { - nextFilename = nextFilename + "." + splitFilename[i]; + nextFilename = nextFilename + '.' + splitFilename[i]; } } this.fileNameCounter++; @@ -1569,7 +1815,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * Disables or enables the input field for the new file name */ setInputFieldVisibility() { - this._("#replace-filename").disabled = !this._("#replace-new-name").checked; + this._('#replace-filename').disabled = !this._('#replace-new-name').checked; } /** @@ -1589,7 +1835,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * */ cancelOverwrite() { - this.statusText = ""; + this.statusText = ''; this.loading = false; this.fileList = []; } @@ -1598,7 +1844,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * */ setRepeatForAllConflicts() { - this.forAll = this._("#replace_mode_all").checked; + this.forAll = this._('#replace_mode_all').checked; } /** @@ -1612,11 +1858,17 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } this._('#new-folder-wrapper').classList.toggle('hidden'); if (this._('#new-folder-wrapper').classList.contains('hidden')) { - this._('#add-folder-button').setAttribute("name", "plus"); - this._('#add-folder-button').setAttribute("title", i18n.t('nextcloud-file-picker.add-folder-open')); + this._('#add-folder-button').setAttribute('name', 'plus'); + this._('#add-folder-button').setAttribute( + 'title', + i18n.t('nextcloud-file-picker.add-folder-open') + ); } else { - this._('#add-folder-button').setAttribute("name", "close"); - this._('#add-folder-button').setAttribute("title", i18n.t('nextcloud-file-picker.add-folder-close')); + this._('#add-folder-button').setAttribute('name', 'close'); + this._('#add-folder-button').setAttribute( + 'title', + i18n.t('nextcloud-file-picker.add-folder-close') + ); this._('#new-folder').focus(); } } @@ -1631,70 +1883,100 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { const d = new Date(); let props = {permissions: 'RGDNVCK'}; var row = { - type: "directory", - filename: "", - basename: "", + type: 'directory', + filename: '', + basename: '', lastmod: d, - props: props + props: props, }; - + const that = this; - - this.tabulatorTable.addRow(row, true, 1).then(() => { - that._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-table > div.tabulator-row:nth-child(1)").setAttribute('id', 'new-folder-row'); - that._('#new-folder-row').classList.toggle('highlighted'); - - that._('#new-folder-row').querySelector("div.tabulator-cell:nth-child(1) > div > span.tabulator-responsive-collapse-toggle-open").classList.add('new-folder-selected'); - that._('#new-folder-row').querySelector("div.tabulator-cell:nth-child(1) > div > span.tabulator-responsive-collapse-toggle-close").classList.add('new-folder-selected'); - - // overwrite date - that._('#new-folder-row').querySelector("div.tabulator-cell:nth-child(6)").innerText = ''; - if (that._('#new-folder-row').querySelector("div.tabulator-responsive-collapse > table > tbody > tr:nth-child(1) > td:nth-child(2)")) { - that._('#new-folder-row').querySelector("div.tabulator-responsive-collapse > table > tbody > tr:nth-child(1) > td:nth-child(2)").innerText = ''; - } - - // add input field - that._('#new-folder-row').querySelector("div.tabulator-cell:nth-child(3)").setAttribute('id', 'new-folder-cell'); - that._('#new-folder-cell').innerHTML = '<input type="text" class="input" name="tf-new-folder" id="tf-new-folder" value="'+ i18n.t('nextcloud-file-picker.new-folder-placeholder') +'" />'; - - that._('#tf-new-folder').addEventListener("keydown", ({key}) => { - if (key === "Enter") { - that.addNewFolder(); - } - }); - that._('#new-folder-row').addEventListener("keydown", event => { - if (event.key === "Escape") { - that.deleteNewFolderEntry(); - event.stopPropagation(); + this.tabulatorTable + .addRow(row, true, 1) + .then(() => { + that._('#directory-content-table') + .querySelector( + 'div.tabulator-tableHolder > div.tabulator-table > div.tabulator-row:nth-child(1)' + ) + .setAttribute('id', 'new-folder-row'); + that._('#new-folder-row').classList.toggle('highlighted'); + + that._('#new-folder-row') + .querySelector( + 'div.tabulator-cell:nth-child(1) > div > span.tabulator-responsive-collapse-toggle-open' + ) + .classList.add('new-folder-selected'); + that._('#new-folder-row') + .querySelector( + 'div.tabulator-cell:nth-child(1) > div > span.tabulator-responsive-collapse-toggle-close' + ) + .classList.add('new-folder-selected'); + + // overwrite date + that + ._('#new-folder-row') + .querySelector('div.tabulator-cell:nth-child(6)').innerText = ''; + if ( + that + ._('#new-folder-row') + .querySelector( + 'div.tabulator-responsive-collapse > table > tbody > tr:nth-child(1) > td:nth-child(2)' + ) + ) { + that + ._('#new-folder-row') + .querySelector( + 'div.tabulator-responsive-collapse > table > tbody > tr:nth-child(1) > td:nth-child(2)' + ).innerText = ''; } - }); - document.addEventListener("keydown", this.boundCancelNewFolderHandler); + // add input field + that._('#new-folder-row') + .querySelector('div.tabulator-cell:nth-child(3)') + .setAttribute('id', 'new-folder-cell'); + that._('#new-folder-cell').innerHTML = + '<input type="text" class="input" name="tf-new-folder" id="tf-new-folder" value="' + + i18n.t('nextcloud-file-picker.new-folder-placeholder') + + '" />'; + + that._('#tf-new-folder').addEventListener('keydown', ({key}) => { + if (key === 'Enter') { + that.addNewFolder(); + } + }); - that._('#new-folder-row').addEventListener("click", (event) => { - that._('#tf-new-folder').select(); - event.stopPropagation(); - }); + that._('#new-folder-row').addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + that.deleteNewFolderEntry(); + event.stopPropagation(); + } + }); - that.initateOpenNewFolder = true; + document.addEventListener('keydown', this.boundCancelNewFolderHandler); - // give the browser a chance to paint before selecting - setTimeout(() => { - this._('#tf-new-folder').select(); - }, 0); - - - }).catch((error) => { - console.log('error', error); - }); + that._('#new-folder-row').addEventListener('click', (event) => { + that._('#tf-new-folder').select(); + event.stopPropagation(); + }); + + that.initateOpenNewFolder = true; + + // give the browser a chance to paint before selecting + setTimeout(() => { + this._('#tf-new-folder').select(); + }, 0); + }) + .catch((error) => { + console.log('error', error); + }); // during folder creation it should not be possible to click something document.addEventListener('click', this.boundClickOutsideNewFolderHandler); } cancelNewFolder(event) { - if (event.key === "Escape") { + if (event.key === 'Escape') { this.deleteNewFolderEntry(); event.stopPropagation(); //TODO verify } @@ -1707,7 +1989,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } this._('#new-folder-row').classList.toggle('highlighted'); - + var row = this.tabulatorTable.getRowFromPosition(0); if (row) { row.delete(); @@ -1715,7 +1997,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.disableRowClick = false; document.removeEventListener('click', this.boundClickOutsideNewFolderHandler); - document.removeEventListener("keydown", this.boundCancelNewFolderHandler); + document.removeEventListener('keydown', this.boundCancelNewFolderHandler); } addNewFolder() { @@ -1727,34 +2009,51 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } this.deleteNewFolderEntry(); - let folderPath = this.directoryPath + "/" + folderName; - this.webDavClient.createDirectory(folderPath).then(contents => { - - const d = new Date(); - let props = {permissions: 'RGDNVCK'}; - this.tabulatorTable.addRow({ - type: "directory", - filename: folderPath, - basename: folderName, - lastmod: d, - props: props - }, true); - this.statusText = i18n.t('nextcloud-file-picker.add-folder-success', {folder: folderName}); - this.loading = false; - - }).catch(error => { - this.loading = false; - if (error.message.search("405") !== -1) { - this.statusText = html`<span - class="error"> ${i18n.t('nextcloud-file-picker.add-folder-error', {folder: folderName})} </span>`; - } else { - this.statusText = html`<span - class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`; - } - }); + let folderPath = this.directoryPath + '/' + folderName; + this.webDavClient + .createDirectory(folderPath) + .then((contents) => { + const d = new Date(); + let props = {permissions: 'RGDNVCK'}; + this.tabulatorTable.addRow( + { + type: 'directory', + filename: folderPath, + basename: folderName, + lastmod: d, + props: props, + }, + true + ); + this.statusText = i18n.t('nextcloud-file-picker.add-folder-success', { + folder: folderName, + }); + this.loading = false; + }) + .catch((error) => { + this.loading = false; + if (error.message.search('405') !== -1) { + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.add-folder-error', { + folder: folderName, + })} + </span> + `; + } else { + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.webdav-error', { + error: error.message, + })} + </span> + `; + } + }); } else { - this.statusText = html`<span - class="error"> ${i18n.t('nextcloud-file-picker.add-folder-error-empty')} </span>`; + this.statusText = html` + <span class="error">${i18n.t('nextcloud-file-picker.add-folder-error-empty')}</span> + `; } } @@ -1764,35 +2063,53 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { */ addFolder() { const i18n = this._i18n; - if (this._('#new-folder').value !== "") { + if (this._('#new-folder').value !== '') { let folderName = this._('#new-folder').value; if (typeof this.directoryPath === 'undefined') { this.directoryPath = ''; } - let folderPath = this.directoryPath + "/" + folderName; - this.webDavClient.createDirectory(folderPath).then(contents => { - // this.loadDirectory(this.directoryPath); - const d = new Date(); - let props = {permissions: 'RGDNVCK'}; - this.tabulatorTable.addRow({ - type: "directory", - filename: folderPath, - basename: folderName, - lastmod: d, - props: props - }, true); - this.statusText = i18n.t('nextcloud-file-picker.add-folder-success', {folder: folderName}); - this.loading = false; - }).catch(error => { - this.loading = false; - if (error.message.search("405") !== -1) { - this.statusText = html`<span - class="error"> ${i18n.t('nextcloud-file-picker.add-folder-error', {folder: folderName})} </span>`; - } else { - this.statusText = html`<span - class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`; - } - }); + let folderPath = this.directoryPath + '/' + folderName; + this.webDavClient + .createDirectory(folderPath) + .then((contents) => { + // this.loadDirectory(this.directoryPath); + const d = new Date(); + let props = {permissions: 'RGDNVCK'}; + this.tabulatorTable.addRow( + { + type: 'directory', + filename: folderPath, + basename: folderName, + lastmod: d, + props: props, + }, + true + ); + this.statusText = i18n.t('nextcloud-file-picker.add-folder-success', { + folder: folderName, + }); + this.loading = false; + }) + .catch((error) => { + this.loading = false; + if (error.message.search('405') !== -1) { + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.add-folder-error', { + folder: folderName, + })} + </span> + `; + } else { + this.statusText = html` + <span class="error"> + ${i18n.t('nextcloud-file-picker.webdav-error', { + error: error.message, + })} + </span> + `; + } + }); this._('#new-folder').value = ''; this.openAddFolderDialogue(); @@ -1806,15 +2123,29 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { selectAllFiles() { let allSelected = this.checkAllSelected(); if (allSelected) { - this.tabulatorTable.getSelectedRows().forEach(row => row.deselect()); + this.tabulatorTable.getSelectedRows().forEach((row) => row.deselect()); } else { - this.tabulatorTable.selectRow(this.tabulatorTable.getRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes))); + this.tabulatorTable.selectRow( + this.tabulatorTable + .getRows() + .filter( + (row) => + row.getData().type != 'directory' && + this.checkFileType(row.getData(), this.allowedMimeTypes) + ) + ); } } checkAllSelected() { if (this.tabulatorTable) { - let maxSelected = this.tabulatorTable.getRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes)).length; + let maxSelected = this.tabulatorTable + .getRows() + .filter( + (row) => + row.getData().type != 'directory' && + this.checkFileType(row.getData(), this.allowedMimeTypes) + ).length; let selected = this.tabulatorTable.getSelectedRows().length; if (selected === maxSelected) { return true; @@ -1842,10 +2173,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { if (typeof this.directoryPath === 'undefined') { this.directoryPath = ''; } - let path = this.directoryPath.replace(/\/$/, ""); - path = path.replace(path.split("/").pop(), "").replace(/\/$/, ""); + let path = this.directoryPath.replace(/\/$/, ''); + path = path.replace(path.split('/').pop(), '').replace(/\/$/, ''); - return (path === "") ? "/" : path; + return path === '' ? '/' : path; } /** @@ -1859,53 +2190,109 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.directoryPath = ''; } let htmlpath = []; - htmlpath[0] = html`<span class="breadcrumb"><a class="home-link" @click="${() => { - this.loadDirectory(""); - }}" title="${i18n.t('nextcloud-file-picker.folder-home')}"><dbp-icon name="home"></dbp-icon> </a></span>`; - - if (this.isInFavorites) { - htmlpath[1] = html`<span class="first"> › </span><span class="breadcrumb special"><a @click="${() => { - this.loadFavorites(); - }}" title="${i18n.t('nextcloud-file-picker.favorites-title')}">${i18n.t('nextcloud-file-picker.favorites-title')}</a></span>`; + htmlpath[0] = html` + <span class="breadcrumb"> + <a + class="home-link" + @click="${() => { + this.loadDirectory(''); + }}" + title="${i18n.t('nextcloud-file-picker.folder-home')}"> + <dbp-icon name="home"></dbp-icon> + </a> + </span> + `; + if (this.isInFavorites) { + htmlpath[1] = html` + <span class="first">›</span> + <span class="breadcrumb special"> + <a + @click="${() => { + this.loadFavorites(); + }}" + title="${i18n.t('nextcloud-file-picker.favorites-title')}"> + ${i18n.t('nextcloud-file-picker.favorites-title')} + </a> + </span> + `; } else if (this.isInRecent) { - htmlpath[1] = html`<span class="first"> › </span><span class="breadcrumb special"><a @click="${() => { - this.loadAllRecentFiles(); - }}" title="${i18n.t('nextcloud-file-picker.recent-files-title')}">${i18n.t('nextcloud-file-picker.recent-files-title')}</a></span>`; - - } else if (this.isInFilteredRecent) { - htmlpath[1] = html`<span class="first"> › </span><span class="breadcrumb special"><a @click="${() => { - this.loadMyRecentFiles(); - }}" title="${i18n.t('nextcloud-file-picker.my-recent-files-title')}">${i18n.t('nextcloud-file-picker.my-recent-files-title')}</a></span>`; - - - } else { // case normal folders + htmlpath[1] = html` + <span class="first">›</span> + <span class="breadcrumb special"> + <a + @click="${() => { + this.loadAllRecentFiles(); + }}" + title="${i18n.t('nextcloud-file-picker.recent-files-title')}"> + ${i18n.t('nextcloud-file-picker.recent-files-title')} + </a> + </span> + `; + } else if (this.isInFilteredRecent) { + htmlpath[1] = html` + <span class="first">›</span> + <span class="breadcrumb special"> + <a + @click="${() => { + this.loadMyRecentFiles(); + }}" + title="${i18n.t('nextcloud-file-picker.my-recent-files-title')}"> + ${i18n.t('nextcloud-file-picker.my-recent-files-title')} + </a> + </span> + `; + } else { + // case normal folders const directories = this.directoryPath.split('/'); - if (directories[1] === "") { + if (directories[1] === '') { return htmlpath; } for (let i = 1; i < directories.length; i++) { - let path = ""; + let path = ''; for (let j = 1; j <= i; j++) { - path += "/"; + path += '/'; path += directories[j]; } if (i === 1) { - htmlpath[i] = html`<span class="first breadcrumb-arrow"> › </span><span class="breadcrumb"><a @click="${() => { - this.loadDirectory(path); - }}" title="${i18n.t('nextcloud-file-picker.load-path-link', {path: directories[i]})}">${directories[i]}</a></span>`; + htmlpath[i] = html` + <span class="first breadcrumb-arrow">›</span> + <span class="breadcrumb"> + <a + @click="${() => { + this.loadDirectory(path); + }}" + title="${i18n.t('nextcloud-file-picker.load-path-link', { + path: directories[i], + })}"> + ${directories[i]} + </a> + </span> + `; } else { - htmlpath[i] = html`<span class="breadcrumb-arrow"> › </span><span class="breadcrumb"><a @click="${() => { - this.loadDirectory(path); - }}" title="${i18n.t('nextcloud-file-picker.load-path-link', {path: directories[i]})}">${directories[i]}</a></span>`; - } + htmlpath[i] = html` + <span class="breadcrumb-arrow">›</span> + <span class="breadcrumb"> + <a + @click="${() => { + this.loadDirectory(path); + }}" + title="${i18n.t('nextcloud-file-picker.load-path-link', { + path: directories[i], + })}"> + ${directories[i]} + </a> + </span> + `; + } } - + let length = htmlpath.length; let width = window.innerWidth; - if (length > 3 && width <= 768) { //breadcrumb longer than 3 && only for mobile view + if (length > 3 && width <= 768) { + //breadcrumb longer than 3 && only for mobile view let path_temp = []; @@ -1914,25 +2301,51 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { // } for (let i = 1; i < directories.length - 1; i++) { - let path = ""; + let path = ''; for (let j = 1; j <= i; j++) { - path += "/"; + path += '/'; path += directories[j]; } - - path_temp[i] = html`<li class="breadcrumb-${i}" id="breadcrumb-${i}"><a @click="${() => { - this.loadDirectory(path); - }}" title="${i18n.t('nextcloud-file-picker.load-path-link', {path: directories[i]})}"><dbp-icon name="folder" class="breadcrumb-folder"></dbp-icon> ${directories[i]}</a></li>`; + + path_temp[i] = html` + <li class="breadcrumb-${i}" id="breadcrumb-${i}"> + <a + @click="${() => { + this.loadDirectory(path); + }}" + title="${i18n.t('nextcloud-file-picker.load-path-link', { + path: directories[i], + })}"> + <dbp-icon name="folder" class="breadcrumb-folder"></dbp-icon> + ${directories[i]} + </a> + </li> + `; } let shortcrumb = []; shortcrumb[0] = htmlpath[0]; - shortcrumb[1] = html`<span class="first breadcrumb-arrow"> › </span> - <span class="breadcrumb"><a class="extended-breadcrumb-link" @click="${() => { this.toggleBreadcrumbMenu(); }}">. . .</a><div class="breadcrumb-menu"><ul class='extended-breadcrumb-menu hidden'>${path_temp}</ul></div></span>`; - + shortcrumb[1] = html` + <span class="first breadcrumb-arrow">›</span> + <span class="breadcrumb"> + <a + class="extended-breadcrumb-link" + @click="${() => { + this.toggleBreadcrumbMenu(); + }}"> + . . . + </a> + <div class="breadcrumb-menu"> + <ul class="extended-breadcrumb-menu hidden"> + ${path_temp} + </ul> + </div> + </span> + `; + shortcrumb[2] = htmlpath[length - 1]; - + return shortcrumb; } } @@ -1941,8 +2354,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } toggleBreadcrumbMenu() { - const menu = this.shadowRoot.querySelector("ul.extended-breadcrumb-menu"); - const menuStart = this.shadowRoot.querySelector("a.extended-breadcrumb-link"); + const menu = this.shadowRoot.querySelector('ul.extended-breadcrumb-menu'); + const menuStart = this.shadowRoot.querySelector('a.extended-breadcrumb-link'); if (menu === null || menuStart === null) { return; @@ -1955,31 +2368,41 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { let topValue = menuStart.getBoundingClientRect().bottom; let topHeight = this._('.nextcloud-header').offsetHeight; - let isMenuOverflow = this.menuHeightBreadcrumb + topHeight >= this._('.wrapper').offsetHeight ? true : false; - - //set max-width to window with + let isMenuOverflow = + this.menuHeightBreadcrumb + topHeight >= this._('.wrapper').offsetHeight ? true : false; + + //set max-width to window with let maxWidth = this._('.wrapper').offsetWidth; - + if (isMenuOverflow && !menu.classList.contains('hidden')) { - let actualHeight = this._('.wrapper').offsetHeight - this._('.nextcloud-nav').offsetHeight; - menu.setAttribute('style', 'position: fixed;top: ' + topValue + 'px;height: ' + actualHeight + 'px;max-width: ' + maxWidth + 'px;overflow-y: auto;'); + let actualHeight = + this._('.wrapper').offsetHeight - this._('.nextcloud-nav').offsetHeight; + menu.setAttribute( + 'style', + 'position: fixed;top: ' + + topValue + + 'px;height: ' + + actualHeight + + 'px;max-width: ' + + maxWidth + + 'px;overflow-y: auto;' + ); menu.scrollTop = 0; this._('.nextcloud-content').setAttribute('style', 'overflow:hidden;'); - } else if (isMenuOverflow && menu.classList.contains('hidden')) { this._('.nextcloud-content').removeAttribute('style', 'overflow:hidden;'); menu.removeAttribute('style'); } // computations for overflow - end - if (!menu.classList.contains('hidden')) { // add event listener for clicking outside of menu + if (!menu.classList.contains('hidden')) { + // add event listener for clicking outside of menu if (!isMenuOverflow) { menu.setAttribute('style', 'max-width: ' + maxWidth + 'px;'); } document.addEventListener('click', this.boundCloseBreadcrumbMenuHandler); this.initateOpenBreadcrumbMenu = true; - } - else { + } else { document.removeEventListener('click', this.boundCloseBreadcrumbMenuHandler); this._('.nextcloud-content').removeAttribute('style', 'overflow:hidden;'); menu.removeAttribute('style'); @@ -1991,9 +2414,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.initateOpenBreadcrumbMenu = false; return; } - const menu = this.shadowRoot.querySelector("ul.extended-breadcrumb-menu"); - if (menu && !menu.classList.contains('hidden')) - this.toggleBreadcrumbMenu(); + const menu = this.shadowRoot.querySelector('ul.extended-breadcrumb-menu'); + if (menu && !menu.classList.contains('hidden')) this.toggleBreadcrumbMenu(); } refreshOnWindowSizeChange() { @@ -2010,8 +2432,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } toggleMoreMenu() { - const menu = this.shadowRoot.querySelector("ul.extended-menu"); - const menuStart = this.shadowRoot.querySelector("a.extended-menu-link"); + const menu = this.shadowRoot.querySelector('ul.extended-menu'); + const menuStart = this.shadowRoot.querySelector('a.extended-menu-link'); if (menu === null || menuStart === null) { return; @@ -2019,11 +2441,11 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { menu.classList.toggle('hidden'); - if (!menu.classList.contains('hidden')) { // add event listener for clicking outside of menu + if (!menu.classList.contains('hidden')) { + // add event listener for clicking outside of menu document.addEventListener('click', this.boundCloseAdditionalMenuHandler); this.initateOpenAdditionalMenu = true; - } - else { + } else { document.removeEventListener('click', this.boundCloseAdditionalMenuHandler); } } @@ -2033,9 +2455,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.initateOpenAdditionalMenu = false; return; } - const menu = this.shadowRoot.querySelector("ul.extended-menu"); - if (menu && !menu.classList.contains('hidden')) - this.toggleMoreMenu(); + const menu = this.shadowRoot.querySelector('ul.extended-menu'); + if (menu && !menu.classList.contains('hidden')) this.toggleMoreMenu(); } static get styles() { @@ -2061,7 +2482,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } .tabulator-placeholder span { - padding: 14px!important; /*TODO find a better way*/ + padding: 14px !important; /*TODO find a better way*/ white-space: normal; } @@ -2096,14 +2517,14 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { max-width: none; display: inline; } - + .nextcloud-nav { position: relative; width: 100%; } .nextcloud-header.hidden { - display: none!important; + display: none !important; } .nextcloud-header { @@ -2143,9 +2564,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { z-index: 1000; /** display: grid; **/ } - + .extended-breadcrumb-menu a:hover { - color: #E4154B; + color: #e4154b; } .button-container.filter-user { @@ -2158,7 +2579,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { color: var(--dbp-text-muted); } - input[type=text]#tf-new-folder:focus { + input[type='text']#tf-new-folder:focus { /* font-weight: 300; */ border: none; background: transparent; @@ -2166,12 +2587,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { height: 100%; } - input[type=text]#tf-new-folder:focus-visible { + input[type='text']#tf-new-folder:focus-visible { outline: none; box-shadow: none; } - input[type=text]#tf-new-folder::placeholder { + input[type='text']#tf-new-folder::placeholder { color: #333; font-weight: 300; } @@ -2196,7 +2617,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { font-weight: 300; } - input[type=text]#tf-new-folder { + input[type='text']#tf-new-folder { border: 0px; background: transparent; width: 100%; @@ -2293,7 +2714,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { .nextcloud-logo-image { height: 100%; width: 100%; - background-image: var(--dbp-override-image-nextcloud, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M69.3 86.1l-46.1 0C11 85.9 1.1 75.9 1.1 63.7c0-11.8 9.1-21.4 20.6-22.4 0.5-15.2 13-27.4 28.3-27.4 3.4 0 6.6 0.5 9.2 1.6 6.2 2.1 11.4 6.4 14.8 12 6.5 1 12.7 4.3 16.9 9.1 5 5.5 7.8 12.6 7.8 19.9C98.8 72.8 85.6 86.1 69.3 86.1zM23.6 80.6h45.7c13.3 0 24-10.8 24-24 0-6-2.3-11.8-6.4-16.2 -3.7-4.2-9.1-6.9-14.9-7.5l-1.4-0.2L70 31.4c-2.8-5.1-7.2-8.9-12.6-10.7l-0.1 0c-2-0.8-4.5-1.2-7.2-1.2 -12.6 0-22.9 10.3-22.9 22.9v4.5h-3.6c-9.3 0-17 7.6-17 17C6.6 73 14.3 80.6 23.6 80.6z'/%3E%3C/svg%3E")); + background-image: var( + --dbp-override-image-nextcloud, + url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M69.3 86.1l-46.1 0C11 85.9 1.1 75.9 1.1 63.7c0-11.8 9.1-21.4 20.6-22.4 0.5-15.2 13-27.4 28.3-27.4 3.4 0 6.6 0.5 9.2 1.6 6.2 2.1 11.4 6.4 14.8 12 6.5 1 12.7 4.3 16.9 9.1 5 5.5 7.8 12.6 7.8 19.9C98.8 72.8 85.6 86.1 69.3 86.1zM23.6 80.6h45.7c13.3 0 24-10.8 24-24 0-6-2.3-11.8-6.4-16.2 -3.7-4.2-9.1-6.9-14.9-7.5l-1.4-0.2L70 31.4c-2.8-5.1-7.2-8.9-12.6-10.7l-0.1 0c-2-0.8-4.5-1.2-7.2-1.2 -12.6 0-22.9 10.3-22.9 22.9v4.5h-3.6c-9.3 0-17 7.6-17 17C6.6 73 14.3 80.6 23.6 80.6z'/%3E%3C/svg%3E") + ); background-repeat: no-repeat; background-position: center; } @@ -2333,13 +2757,11 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { -webkit-overflow-scrolling: touch; } - .nextcloud-nav { display: flex; justify-content: space-between; } - .nextcloud-footer { background-color: var(--dbp-base); width: 100%; @@ -2354,7 +2776,6 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { justify-content: space-between; } - .additional-menu { white-space: nowrap; height: 33px; @@ -2410,7 +2831,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { margin-top: 8px; } - #replace-modal-box input[type="text"]:disabled { + #replace-modal-box input[type='text']:disabled { color: var(--dbp-text-muted); } @@ -2432,7 +2853,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { border-bottom: var(--dbp-border); } - .breadcrumb:last-child, .breadcrumb:first-child { + .breadcrumb:last-child, + .breadcrumb:first-child { border-bottom: none; } @@ -2441,7 +2863,6 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { height: 33px; vertical-align: middle; line-height: 33px; - } input:disabled + label { @@ -2456,7 +2877,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { padding-top: 10px; } - .no-select, .tabulator-row.tabulator-selected.no-select:hover, .tabulator-row.no-select:hover, .tabulator-row.tabulator-selectable.no-select:hover { + .no-select, + .tabulator-row.tabulator-selected.no-select:hover, + .tabulator-row.no-select:hover, + .tabulator-row.tabulator-selectable.no-select:hover { cursor: unset; color: var(--dbp-text); background-color: var(--dbp-base); @@ -2483,7 +2907,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { #abortButton:hover { color: var(--dbp-text-inverted); } - + .menu-buttons { display: flex; gap: 1em; @@ -2509,7 +2933,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { opacity: 0.4; } - .button.button, .button, button.dt-button { + .button.button, + .button, + button.dt-button { background-color: var(--dbp-base); } @@ -2558,21 +2984,21 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { left: 11px; top: 4px; } - + #replace-modal .checkmark { height: 20px; width: 20px; left: 1px; top: 0px; } - - .remember-container{ + + .remember-container { display: inline-block; line-height: 28px; padding-left: 34px; } - .remember-container .checkmark{ + .remember-container .checkmark { left: 7px; } @@ -2587,10 +3013,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { font-size: 1.4em; } - @media only screen - and (orientation: portrait) - and (max-width: 768px) { - + @media only screen and (orientation: portrait) and (max-width: 768px) { .breadcrumb-arrow { font-size: 1.6em; vertical-align: middle; @@ -2606,7 +3029,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { .extended-breadcrumb-link { margin-top: -4px; /**TODO -3px; -2px;*/ - font-size: 1.2em!important; /**TODO for demo purpose only */ + font-size: 1.2em !important; /**TODO for demo purpose only */ font-weight: 400; } @@ -2672,7 +3095,6 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { margin: 0 auto; } - .button-wrapper { justify-self: start; } @@ -2687,7 +3109,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { margin-bottom: 0px; } - .nextcloud-content, .nextcloud-intro { + .nextcloud-content, + .nextcloud-intro { grid-area: content; height: 100%; justify-content: center; @@ -2752,53 +3175,77 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { width: 25px; left: 9px; top: 2px; */ - } - } `; } render() { const i18n = this._i18n; - const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css'); + const tabulatorCss = commonUtils.getAssetURL( + pkgName, + 'tabulator-tables/css/tabulator.min.css' + ); return html` <div class="wrapper"> - <link rel="stylesheet" href="${tabulatorCss}"> + <link rel="stylesheet" href="${tabulatorCss}" /> <div class="nextcloud-intro ${classMap({hidden: this.isPickerActive})}"> - <div class="nextcloud-logo ${classMap({"nextcloud-logo-sm": this.isPickerActive})}"> + <div + class="nextcloud-logo ${classMap({ + 'nextcloud-logo-sm': this.isPickerActive, + })}"> <div class="nextcloud-logo-image"></div> </div> <div class="block text-center ${classMap({hidden: this.isPickerActive})}"> - <h2 class="m-inherit"> - ${this.nextcloudName} - </h2> + <h2 class="m-inherit">${this.nextcloudName}</h2> <p class="m-inherit"> - ${i18n.t('nextcloud-file-picker.init-text-1', {name: this.nextcloudName})} <br> - ${i18n.t('nextcloud-file-picker.init-text-2')} <br><br> + ${i18n.t('nextcloud-file-picker.init-text-1', { + name: this.nextcloudName, + })} + <br /> + ${i18n.t('nextcloud-file-picker.init-text-2')} + <br /> + <br /> </p> </div> <div class="block ${classMap({hidden: this.isPickerActive})}"> - <button class="button is-primary" - title="${i18n.t('nextcloud-file-picker.open-nextcloud-file-picker', {name: this.nextcloudName})}" - @click="${async () => { - this.openFilePicker(); - }}">${i18n.t('nextcloud-file-picker.connect-nextcloud', {name: this.nextcloudName})} + <button + class="button is-primary" + title="${i18n.t('nextcloud-file-picker.open-nextcloud-file-picker', { + name: this.nextcloudName, + })}" + @click="${async () => { + this.openFilePicker(); + }}"> + ${i18n.t('nextcloud-file-picker.connect-nextcloud', { + name: this.nextcloudName, + })} </button> </div> - <div class="block text-center m-inherit ${classMap({hidden: !this.storeSession || !this.isLoggedIn()})}"> + <div + class="block text-center m-inherit ${classMap({ + hidden: !this.storeSession || !this.isLoggedIn(), + })}"> <label class="button-container remember-container"> - ${i18n.t('nextcloud-file-picker.remember-me', {name: this.nextcloudName})} - <input type="checkbox" id="remember-checkbox" name="remember"> + ${i18n.t('nextcloud-file-picker.remember-me', { + name: this.nextcloudName, + })} + <input type="checkbox" id="remember-checkbox" name="remember" /> <span class="checkmark"></span> </label> </div> - <div class="block text-center m-inherit ${classMap({hidden: this.isPickerActive})}"> - <p class="m-inherit"><br> + <div + class="block text-center m-inherit ${classMap({ + hidden: this.isPickerActive, + })}"> + <p class="m-inherit"> + <br /> ${i18n.t('nextcloud-file-picker.auth-info')} - <slot name="auth-info"><br/>${this.authInfo}</slot> + <slot name="auth-info"> + <br /> + ${this.authInfo} + </slot> </p> - </div> </div> <div class="nextcloud-header ${classMap({hidden: !this.isPickerActive})}"> @@ -2806,43 +3253,71 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { <p>${this.getBreadcrumb()}</p> <div class="additional-menu ${classMap({hidden: !this.storeSession})}"> - - <a class="extended-menu-link" @click="${() => { this.toggleMoreMenu(); }}" title="${i18n.t('nextcloud-file-picker.more-menu')}"> + <a + class="extended-menu-link" + @click="${() => { + this.toggleMoreMenu(); + }}" + title="${i18n.t('nextcloud-file-picker.more-menu')}"> <dbp-icon name="menu-dots" class="more-menu"></dbp-icon> </a> - <ul class='extended-menu hidden'> - <li class="${classMap({active: this.isInFavorites})}" id="favorites-item"> + <ul class="extended-menu hidden"> + <li + class="${classMap({active: this.isInFavorites})}" + id="favorites-item"> <a class="" @click="${this.loadFavorites}"> ${i18n.t('nextcloud-file-picker.favorites-link-text')} </a> </li> - <li class="${classMap({active: this.isInFilteredRecent})}" id="my-recent-item"> + <li + class="${classMap({active: this.isInFilteredRecent})}" + id="my-recent-item"> <a class="" @click="${this.loadMyRecentFiles}"> ${i18n.t('nextcloud-file-picker.my-recent-files-link-text')} </a> </li> - <li class="${classMap({active: this.isInRecent})}" id="all-recent-item"> + <li + class="${classMap({active: this.isInRecent})}" + id="all-recent-item"> <a class="" @click="${this.loadAllRecentFiles}"> - ${i18n.t('nextcloud-file-picker.all-recent-files-link-text')} + ${i18n.t( + 'nextcloud-file-picker.all-recent-files-link-text' + )} </a> </li> <li class="${classMap({hidden: !this.directoriesOnly})}"> - <a class="${classMap({inactive: this.isInRecent || this.isInFavorites || this.isInFilteredRecent || this.disableRowClick})}" @click="${() => { this.addOpenFolderTableEntry(); }}"> + <a + class="${classMap({ + inactive: + this.isInRecent || + this.isInFavorites || + this.isInFilteredRecent || + this.disableRowClick, + })}" + @click="${() => { + this.addOpenFolderTableEntry(); + }}"> ${i18n.t('nextcloud-file-picker.add-folder')} </a> </li> - - <li class="${classMap({hidden: !this.storeSession})}" title="${i18n.t('nextcloud-file-picker.log-out')}"> - <a class="" @click="${() => { this.logOut(); this.hideAdditionalMenu(); }}"> + + <li + class="${classMap({hidden: !this.storeSession})}" + title="${i18n.t('nextcloud-file-picker.log-out')}"> + <a + class="" + @click="${() => { + this.logOut(); + this.hideAdditionalMenu(); + }}"> ${i18n.t('nextcloud-file-picker.log-out')} </a> </li> </ul> </div> - </div> + </div> </div> <div class="nextcloud-content ${classMap({hidden: !this.isPickerActive})}"> - <div class="table-wrapper"> <table id="directory-content-table" class="force-no-select"></table> </div> @@ -2850,50 +3325,87 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { <div class="nextcloud-footer ${classMap({hidden: !this.isPickerActive})}"> <div class="nextcloud-footer-grid"> - <button id="download-button" - class="button select-button is-primary ${classMap({hidden: ((!this.directoriesOnly) || (this.directoriesOnly && this.abortUploadButton && this.forAll))})}" - @click="${() => { - this.sendDirectory(this.tabulatorTable.getSelectedData()); - }}" - ?disabled="${this.selectBtnDisabled}"> + <button + id="download-button" + class="button select-button is-primary ${classMap({ + hidden: + !this.directoriesOnly || + (this.directoriesOnly && this.abortUploadButton && this.forAll), + })}" + @click="${() => { + this.sendDirectory(this.tabulatorTable.getSelectedData()); + }}" + ?disabled="${this.selectBtnDisabled}"> <dbp-icon class="nav-icon" name="cloud-upload"></dbp-icon> ${this.folderIsSelected} </button> - <button class="button select-button is-primary ${classMap({hidden: this.directoriesOnly})}" - @click="${() => { - this.downloadFiles(this.tabulatorTable.getSelectedData()); - }}" - ?disabled="${this.selectBtnDisabled}"> - ${(this.tabulatorTable && this.tabulatorTable.getSelectedRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes)).length === 0) ? i18n.t('nextcloud-file-picker.select-files') : i18n.t('nextcloud-file-picker.select-files-btn', {count: this.tabulatorTable ? this.tabulatorTable.getSelectedRows().length : 0})} + <button + class="button select-button is-primary ${classMap({ + hidden: this.directoriesOnly, + })}" + @click="${() => { + this.downloadFiles(this.tabulatorTable.getSelectedData()); + }}" + ?disabled="${this.selectBtnDisabled}"> + ${this.tabulatorTable && + this.tabulatorTable + .getSelectedRows() + .filter( + (row) => + row.getData().type != 'directory' && + this.checkFileType(row.getData(), this.allowedMimeTypes) + ).length === 0 + ? i18n.t('nextcloud-file-picker.select-files') + : i18n.t('nextcloud-file-picker.select-files-btn', { + count: this.tabulatorTable + ? this.tabulatorTable.getSelectedRows().length + : 0, + })} </button> - <button id="abortButton" - class="button select-button hidden ${classMap({"visible": (this.directoriesOnly && this.forAll && this.abortUploadButton)})}" - title="${i18n.t('nextcloud-file-picker.abort')}" @click="${() => { - this.abortUpload = true; - }}">${i18n.t('nextcloud-file-picker.abort')} + <button + id="abortButton" + class="button select-button hidden ${classMap({ + visible: + this.directoriesOnly && this.forAll && this.abortUploadButton, + })}" + title="${i18n.t('nextcloud-file-picker.abort')}" + @click="${() => { + this.abortUpload = true; + }}"> + ${i18n.t('nextcloud-file-picker.abort')} </button> - <div class="block info-box ${classMap({hidden: this.statusText === ""})}"> + <div class="block info-box ${classMap({hidden: this.statusText === ''})}"> <dbp-mini-spinner - class="spinner ${classMap({hidden: this.loading === false})}"></dbp-mini-spinner> + class="spinner ${classMap({ + hidden: this.loading === false, + })}"></dbp-mini-spinner> <span>${this.statusText}</span> </div> - </div> </div> </div> <div class="modal micromodal-slide" id="replace-modal" aria-hidden="true"> <div class="modal-overlay" tabindex="-2" data-micromodal-close> - <div class="modal-container" id="replace-modal-box" role="dialog" aria-modal="true" - aria-labelledby="replace-modal-title"> + <div + class="modal-container" + id="replace-modal-box" + role="dialog" + aria-modal="true" + aria-labelledby="replace-modal-title"> <header class="modal-header"> - <button title="${i18n.t('file-sink.modal-close')}" class="modal-close" - aria-label="Close modal" @click="${() => { - this.closeDialog(); - }}"> - <dbp-icon title="${i18n.t('file-sink.modal-close')}" name="close" - class="close-icon"></dbp-icon> + <button + title="${i18n.t('file-sink.modal-close')}" + class="modal-close" + aria-label="Close modal" + @click="${() => { + this.closeDialog(); + }}"> + <dbp-icon + title="${i18n.t('file-sink.modal-close')}" + name="close" + class="close-icon"></dbp-icon> </button> <h2 id="replace-modal-title"> ${i18n.t('nextcloud-file-picker.replace-title-1')} @@ -2902,67 +3414,92 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { </h2> </header> <main class="modal-content" id="replace-modal-content"> - <h3> - ${i18n.t('nextcloud-file-picker.replace-text')}? - </h3> + <h3>${i18n.t('nextcloud-file-picker.replace-text')}?</h3> <div> <label class="button-container"> - <span> + <span> ${i18n.t('nextcloud-file-picker.replace-new_name')}: - </span> - <input type="radio" id="replace-new-name" class="radio-btn" name="replacement" - value="new-name" checked @click="${() => { - this.setInputFieldVisibility(); - }}"> + <input + type="radio" + id="replace-new-name" + class="radio-btn" + name="replacement" + value="new-name" + checked + @click="${() => { + this.setInputFieldVisibility(); + }}" /> <span class="radiobutton"></span> - <input type="text" id="replace-filename" class="input" name="replace-filename" - value="" onClick="this.select();"> + <input + type="text" + id="replace-filename" + class="input" + name="replace-filename" + value="" + onClick="this.select();" /> </label> - </div> - <div> <label class="button-container"> <span>${i18n.t('nextcloud-file-picker.replace-replace')}</span> - <input type="radio" id="replace-replace" name="replacement" value="replace" - @click="${() => { - this.setInputFieldVisibility(); - }}"> + <input + type="radio" + id="replace-replace" + name="replacement" + value="replace" + @click="${() => { + this.setInputFieldVisibility(); + }}" /> <span class="radiobutton"></span> </label> </div> <div> <label class="button-container"> <span>${i18n.t('nextcloud-file-picker.replace-skip')}</span> - <input type="radio" class="radio-btn" name="replacement" value="ignore" - @click="${() => { - this.setInputFieldVisibility(); - }}"> + <input + type="radio" + class="radio-btn" + name="replacement" + value="ignore" + @click="${() => { + this.setInputFieldVisibility(); + }}" /> <span class="radiobutton"></span> </label> </div> </main> <footer class="modal-footer"> <div class="modal-footer-btn"> - <button class="button" data-micromodal-close aria-label="Close this dialog window" - @click="${() => { - this.cancelOverwrite(); - }}">${this.getCancelText()} + <button + class="button" + data-micromodal-close + aria-label="Close this dialog window" + @click="${() => { + this.cancelOverwrite(); + }}"> + ${this.getCancelText()} </button> - <button class="button select-button is-primary" @click="${() => { - this.uploadFileAfterConflict(); - }}">OK + <button + class="button select-button is-primary" + @click="${() => { + this.uploadFileAfterConflict(); + }}"> + OK </button> </div> <div> <label class="button-container"> ${i18n.t('nextcloud-file-picker.replace-mode-all')} - <input type="checkbox" id="replace_mode_all" name="replace_mode_all" - value="replace_mode_all" @click="${() => { - this.setRepeatForAllConflicts(); - }}"> + <input + type="checkbox" + id="replace_mode_all" + name="replace_mode_all" + value="replace_mode_all" + @click="${() => { + this.setRepeatForAllConflicts(); + }}" /> <span class="checkmark"></span> </label> </div> diff --git a/packages/file-handling/src/styles.js b/packages/file-handling/src/styles.js index 56b48c855332650ae3de0d60a6171c4b179e0543..57b503081a84e82f43794c10e9a69f50f7292a68 100644 --- a/packages/file-handling/src/styles.js +++ b/packages/file-handling/src/styles.js @@ -2,7 +2,7 @@ import {css} from 'lit'; export function getFileHandlingCss() { // language=css - return css` + return css` /**************************\\ Modal Styles \\**************************/ @@ -11,7 +11,7 @@ export function getFileHandlingCss() { grid-template-columns: 150px 1fr; grid-template-rows: auto 1fr; gap: 1px 1px; - grid-template-areas: "sidebar header" "sidebar main"; + grid-template-areas: 'sidebar header' 'sidebar main'; position: relative; } @@ -33,7 +33,7 @@ export function getFileHandlingCss() { height: 35px; } - .modal-nav .active{ + .modal-nav .active { background-color: var(--dbp-base-inverted); color: var(--dbp-text-inverted); } @@ -52,7 +52,7 @@ export function getFileHandlingCss() { /*align-items: center;*/ height: 100%; width: 100%; - display:flex; + display: flex; align-items: flex-end; } @@ -60,7 +60,7 @@ export function getFileHandlingCss() { display: none; } - .modal-header{ + .modal-header { grid-area: header; display: flex; padding: 10px 20px 0px 20px; @@ -69,8 +69,7 @@ export function getFileHandlingCss() { align-items: center; } - - .clipboard-container{ + .clipboard-container { height: 100%; display: flex; align-items: center; @@ -79,7 +78,8 @@ export function getFileHandlingCss() { overflow-x: auto; } - .micromodal-slide .modal-container, .micromodal-slide .modal-overlay{ + .micromodal-slide .modal-container, + .micromodal-slide .modal-overlay { will-change: auto; } @@ -87,7 +87,8 @@ export function getFileHandlingCss() { Picker Styles \\**************************/ - #nextcloud-file-picker, #clipboard-file-picker { + #nextcloud-file-picker, + #clipboard-file-picker { width: 100%; height: 100%; margin: var(--FUMargin, 0px); @@ -106,32 +107,46 @@ export function getFileHandlingCss() { display: none; } - #modal-picker-content{ + #modal-picker-content { grid-area: main; } - - - + /**********************************\\ Tabulator table styles \\*********************************/ - - .tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{ + .tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title { padding-top: 4px; padding-bottom: 4px; font-weight: normal; font-size: 1rem; } - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow, - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow, - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow{ + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='asc'] + .tabulator-col-content + .tabulator-arrow, + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='none'] + .tabulator-col-content + .tabulator-arrow, + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='desc'] + .tabulator-col-content + .tabulator-arrow { padding-bottom: 6px; } - .tabulator .tabulator-header, .tabulator .tabulator-header, .tabulator .tabulator-header .tabulator-col, .tabulator, .tabulator-row .tabulator-cell, .tabulator-row.tabulator-row-even, - .tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover{ + .tabulator .tabulator-header, + .tabulator .tabulator-header, + .tabulator .tabulator-header .tabulator-col, + .tabulator, + .tabulator-row .tabulator-cell, + .tabulator-row.tabulator-row-even, + .tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover { background-color: unset; background: unset; color: unset; @@ -139,84 +154,117 @@ export function getFileHandlingCss() { font-size: 1rem; } - .tabulator-row, .tabulator-row.tabulator-row-even{ + .tabulator-row, + .tabulator-row.tabulator-row-even { background-color: var(--dbp-base); } - .tabulator-row.tabulator-selectable.tabulator-selectable:hover{ + .tabulator-row.tabulator-selectable.tabulator-selectable:hover { background-color: var(--dbp-base); color: var(--dbp-text); } - .tabulator-row.tabulator-selectable.tabulator-selected:hover, .tabulator-row.tabulator-selected{ + .tabulator-row.tabulator-selectable.tabulator-selected:hover, + .tabulator-row.tabulator-selected { background-color: var(--dbp-hover-base, var(--dbp-base-inverted)); color: var(--dbp-hover-text, var(--dbp-text-inverted)); } - .tabulator .tabulator-header .tabulator-col .tabulator-col-content{ + .tabulator .tabulator-header .tabulator-col .tabulator-col-content { display: inline-flex; } - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow{ + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='desc'] + .tabulator-col-content + .tabulator-arrow { top: 16px; } - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow{ + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='asc'] + .tabulator-col-content + .tabulator-arrow { border-top: none; border-bottom: 4px solid var(--dbp-text-muted); } - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow{ + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='none'] + .tabulator-col-content + .tabulator-arrow { border-top: none; border-bottom: 4px solid var(--dbp-text-muted); } - .tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow{ + .tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow { border-left: 4px solid transparent; border-right: 4px solid transparent; } - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow, - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow{ + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='desc'] + .tabulator-col-content + .tabulator-arrow, + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='desc'] + .tabulator-col-content + .tabulator-arrow { border-top: 4px solid var(--dbp-text-muted); border-bottom: none; } - .tabulator-row, .tabulator-row.tabulator-row-even{ + .tabulator-row, + .tabulator-row.tabulator-row-even { padding-top: 10px; padding-bottom: 10px; border-top: 1px solid #eee; color: var(--dbp-text); } - .tabulator-row.tabulator-row-even.tabulator-selected{ + .tabulator-row.tabulator-row-even.tabulator-selected { color: var(--dbp-hover-text, var(--dbp-text-inverted)); } - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{ + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='asc'] + .tabulator-col-content + .tabulator-col-sorter + .tabulator-arrow { border-bottom-color: var(--dbp-text); } - .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{ + .tabulator + .tabulator-header + .tabulator-col.tabulator-sortable[aria-sort='none'] + .tabulator-col-content + .tabulator-col-sorter + .tabulator-arrow { border-bottom-color: var(--dbp-text-muted); } - .tabulator-header{ + .tabulator-header { padding-top: 10px; padding-bottom: 10px; } - .tabulator .tabulator-tableHolder{ + .tabulator .tabulator-tableHolder { overflow: hidden; } - .tabulator .tabulator-tableHolder .tabulator-placeholder span{ + .tabulator .tabulator-tableHolder .tabulator-placeholder span { font-size: inherit; font-weight: inherit; color: inherit; } - .force-no-select{ + .force-no-select { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; @@ -224,14 +272,14 @@ export function getFileHandlingCss() { } .tabulator .tabulator-tableHolder { - /* height: unset !important; /*TODO find a better way to do this*/ + /* height: unset !important; /*TODO find a better way to do this*/ } - .tabulator-row .tabulator-responsive-collapse{ + .tabulator-row .tabulator-responsive-collapse { border: none; } - .tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle{ + .tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle { height: 32px; width: 32px; background-color: unset; @@ -239,22 +287,23 @@ export function getFileHandlingCss() { font-size: 1.3em; margin-top: -8px; } - - .tabulator-responsive-collapse-toggle-open, .tabulator-responsive-collapse-toggle-close{ + + .tabulator-responsive-collapse-toggle-open, + .tabulator-responsive-collapse-toggle-close { width: 100%; height: 100%; line-height: 37px; } - .tabulator-responsive-collapse-toggle-open, .tabulator-responsive-collapse-toggle-close{ + .tabulator-responsive-collapse-toggle-open, + .tabulator-responsive-collapse-toggle-close { content: none; visibility: hidden; } .tabulator-responsive-collapse-toggle-open::after { - content: ""; - background-image: - url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjAuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzJfMV8iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAxMDAgMTAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxwYXRoIGQ9Ik0yOS42LDk3LjZsNDQuMi00NC40YzAuOS0wLjksMS4zLTIuMSwxLjMtMy4zYzAtMS4yLTAuNS0yLjQtMS4zLTMuM0wyOS42LDIuNGMtMS4xLTEuMS0yLjgtMS4xLTMuOSwwCgljLTAuNSwwLjUtMC44LDEuMi0wLjgsMS45YzAsMC43LDAuMywxLjQsMC44LDEuOWw0My42LDQzLjZMMjUuNyw5My43Yy0xLjEsMS4xLTEuMSwyLjgsMCwzLjlDMjYuOCw5OC43LDI4LjUsOTguNywyOS42LDk3LjZ6Ii8+Cjwvc3ZnPgo="); + content: ''; + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjAuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzJfMV8iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAxMDAgMTAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxwYXRoIGQ9Ik0yOS42LDk3LjZsNDQuMi00NC40YzAuOS0wLjksMS4zLTIuMSwxLjMtMy4zYzAtMS4yLTAuNS0yLjQtMS4zLTMuM0wyOS42LDIuNGMtMS4xLTEuMS0yLjgtMS4xLTMuOSwwCgljLTAuNSwwLjUtMC44LDEuMi0wLjgsMS45YzAsMC43LDAuMywxLjQsMC44LDEuOWw0My42LDQzLjZMMjUuNyw5My43Yy0xLjEsMS4xLTEuMSwyLjgsMCwzLjlDMjYuOCw5OC43LDI4LjUsOTguNywyOS42LDk3LjZ6Ii8+Cjwvc3ZnPgo='); visibility: visible; position: absolute; width: 100%; @@ -266,11 +315,10 @@ export function getFileHandlingCss() { background-position: center center; background-size: 1rem; } - + .tabulator-responsive-collapse-toggle-close::after { - content: ""; - background-image: - url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjAuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzJfMV8iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAxMDAgMTAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxwYXRoIGQ9Ik0yLjQsMjkuNmw0NC40LDQ0LjJjMC45LDAuOSwyLjEsMS4zLDMuMywxLjNjMS4yLDAsMi40LTAuNSwzLjMtMS4zbDQ0LjItNDQuMmMxLjEtMS4xLDEuMS0yLjgsMC0zLjkKCWMtMC41LTAuNS0xLjItMC44LTEuOS0wLjhjLTAuNywwLTEuNCwwLjMtMS45LDAuOEw1MC4xLDY5LjNMNi4zLDI1LjdjLTEuMS0xLjEtMi44LTEuMS0zLjksMEMxLjMsMjYuOCwxLjMsMjguNSwyLjQsMjkuNnoiLz4KPC9zdmc+Cg=="); + content: ''; + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjAuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzJfMV8iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAxMDAgMTAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxwYXRoIGQ9Ik0yLjQsMjkuNmw0NC40LDQ0LjJjMC45LDAuOSwyLjEsMS4zLDMuMywxLjNjMS4yLDAsMi40LTAuNSwzLjMtMS4zbDQ0LjItNDQuMmMxLjEtMS4xLDEuMS0yLjgsMC0zLjkKCWMtMC41LTAuNS0xLjItMC44LTEuOS0wLjhjLTAuNywwLTEuNCwwLjMtMS45LDAuOEw1MC4xLDY5LjNMNi4zLDI1LjdjLTEuMS0xLjEtMi44LTEuMS0zLjksMEMxLjMsMjYuOCwxLjMsMjguNSwyLjQsMjkuNnoiLz4KPC9zdmc+Cg=='); visibility: visible; position: absolute; width: 100%; @@ -282,25 +330,22 @@ export function getFileHandlingCss() { background-position: center center; background-size: 1rem; } - - .tabulator-row-handle{ + + .tabulator-row-handle { padding: 0px !important; } - - .tabulator-selected .tabulator-responsive-collapse-toggle-open, - .tabulator-selected .tabulator-responsive-collapse-toggle-close{ + + .tabulator-selected .tabulator-responsive-collapse-toggle-open, + .tabulator-selected .tabulator-responsive-collapse-toggle-close { color: var(--dbp-text-inverted); } - - .tabulator .tabulator-header .tabulator-col{ + + .tabulator .tabulator-header .tabulator-col { min-height: 37px !important; } - @media only screen - and (orientation: portrait) - and (max-width: 768px) { - - .tabulator .tabulator-tableHolder{ + @media only screen and (orientation: portrait) and (max-width: 768px) { + .tabulator .tabulator-tableHolder { white-space: inherit; } @@ -311,18 +356,12 @@ export function getFileHandlingCss() { } } - - - /**************************\\ Tablett Portrait Styles \\**************************/ - - @media only screen - and (orientation: portrait) - and (max-width: 768px) { - .modal-nav{ + @media only screen and (orientation: portrait) and (max-width: 768px) { + .modal-nav { display: flex; /*justify-content: space-around;*/ grid-area: nav; @@ -339,30 +378,31 @@ export function getFileHandlingCss() { display: none; } - .modal-content{ + .modal-content { grid-area: main; } - .modal-container{ + .modal-container { grid-template-rows: 40px 55px auto; - grid-template-areas: "header" "nav" "main"; + grid-template-areas: 'header' 'nav' 'main'; grid-template-columns: auto; } - .modal-header{ + .modal-header { grid-area: header; padding: 5px; } - .modal-nav > div{ + .modal-nav > div { flex-grow: 1; } - .modal-nav .nav-icon{ + .modal-nav .nav-icon { height: 20px; } - #nextcloud-file-picker, #clipboard-file-picker{ + #nextcloud-file-picker, + #clipboard-file-picker { padding: 0px; } } @@ -370,18 +410,8 @@ export function getFileHandlingCss() { /**************************\\ Mobile Portrait Styles \\**************************/ - - @media only screen - and (orientation: portrait) - and (max-width: 768px) { - - - - - - + @media only screen and (orientation: portrait) and (max-width: 768px) { } - `; -} \ No newline at end of file +} diff --git a/packages/file-handling/test/crypto.js b/packages/file-handling/test/crypto.js index b6f9f27005798d03e752efc688b25c8bcf9ce1de..f497d5fb927f154a44591c63dd1e076b9dd163af 100644 --- a/packages/file-handling/test/crypto.js +++ b/packages/file-handling/test/crypto.js @@ -1,7 +1,6 @@ import {assert} from '@esm-bundle/chai'; import {encrypt, decrypt} from '../src/crypto'; - suite('encyptAndDecrypt', () => { test('encrypt', async () => { let res = await encrypt('token', 'my-payload'); diff --git a/packages/file-handling/test/unit.js b/packages/file-handling/test/unit.js index 2474b33cafecbc605ee8b03f315f57c9db4e6696..737ee57d754de4082879d189829189da16547cb4 100644 --- a/packages/file-handling/test/unit.js +++ b/packages/file-handling/test/unit.js @@ -4,37 +4,37 @@ import '../src/dbp-file-source'; import '../src/demo'; suite('dbp-file-source basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-file-source'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-file-source'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); suite('dbp-file-source demo', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-file-source-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-file-source-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/knowledge-base-web-page-element-view/.eslintrc.json b/packages/knowledge-base-web-page-element-view/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/knowledge-base-web-page-element-view/.eslintrc.json +++ b/packages/knowledge-base-web-page-element-view/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/knowledge-base-web-page-element-view/.prettierignore b/packages/knowledge-base-web-page-element-view/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/knowledge-base-web-page-element-view/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/knowledge-base-web-page-element-view/.prettierrc.json b/packages/knowledge-base-web-page-element-view/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/knowledge-base-web-page-element-view/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/knowledge-base-web-page-element-view/package.json b/packages/knowledge-base-web-page-element-view/package.json index f7d85fc39959cf397da54893e15c265011e1b94f..d256658982d3546cc668ecd416abf6db40f00c88 100644 --- a/packages/knowledge-base-web-page-element-view/package.json +++ b/packages/knowledge-base-web-page-element-view/package.json @@ -1,59 +1,63 @@ { - "name": "@dbp-toolkit/knowledge-base-web-page-element-view", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/knowledge-base-web-page-element-view", - "version": "0.2.3", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/knowledge-base-web-page-element-view" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "i18next": "^21.4.2", - "lit": "^2.0.0", - "material-design-icons-svg": "^3.0.0" - }, - "scripts": { - "i18next": "i18next-scanner", - "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", - "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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/knowledge-base-web-page-element-view", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/knowledge-base-web-page-element-view", + "version": "0.2.3", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/knowledge-base-web-page-element-view" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "i18next": "^21.4.2", + "lit": "^2.0.0", + "material-design-icons-svg": "^3.0.0" + }, + "scripts": { + "i18next": "i18next-scanner", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "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", + "lint": "eslint ." + } } diff --git a/packages/knowledge-base-web-page-element-view/rollup.config.js b/packages/knowledge-base-web-page-element-view/rollup.config.js index 4d768f0c420dbc4c4a0704eb8397ffbdba913596..332ed2fc125dfc57cbde22e68d62a11469ffb471 100644 --- a/packages/knowledge-base-web-page-element-view/rollup.config.js +++ b/packages/knowledge-base-web-page-element-view/rollup.config.js @@ -2,29 +2,35 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url"; +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build != 'test') ? ['src/dbp-knowledge-base-web-page-element-view.js', 'src/dbp-knowledge-base-web-page-element-view-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? [ + 'src/dbp-knowledge-base-web-page-element-view.js', + 'src/dbp-knowledge-base-web-page-element-view-demo.js', + ] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), @@ -32,17 +38,22 @@ export default (async () => { url({ limit: 0, emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, {src: 'assets/favicon.ico', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js index 6c72e009c9e39d69e8b536c22bc1c2673ca39bfe..84ad091a1c0389a5716b466575c16c5203caed15 100644 --- a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js +++ b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js @@ -5,7 +5,7 @@ import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; import {KnowledgeBaseWebPageElementView} from './knowledge-base-web-page-element-view.js'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { @@ -18,24 +18,24 @@ export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(DBP static get scopedElements() { return { - 'dbp-knowledge-base-web-page-element-view' : KnowledgeBaseWebPageElementView, - 'dbp-auth-keycloak': AuthKeycloak, - 'dbp-login-button': LoginButton, + 'dbp-knowledge-base-web-page-element-view': KnowledgeBaseWebPageElementView, + 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-login-button': LoginButton, }; } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - noAuth: { type: Boolean, attribute: 'no-auth' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + noAuth: {type: Boolean, attribute: 'no-auth'}, }; } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -46,8 +46,12 @@ export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(DBP static get styles() { // language=css const styles = css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } .clean { --KBBorder: initial; @@ -60,22 +64,28 @@ export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(DBP } `; - return [ - commonStyles.getThemeCSS(), - commonStyles.getGeneralCSS(), - styles, - ]; + return [commonStyles.getThemeCSS(), commonStyles.getGeneralCSS(), styles]; } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button>` : html` - <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" - url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" - client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> - <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> - </div> - `; + return this.noAuth + ? html` + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + ` + : html` + <div class="container"> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + url="https://auth-dev.tugraz.at/auth" + realm="tugraz-vpu" + client-id="auth-dev-mw-frontend-local" + try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + </div> + `; } render() { return html` @@ -87,27 +97,48 @@ export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(DBP <div class="container"> <h2 class="subtitle">Deutsch</h2> <p>Ein erster Schritt</p> - <dbp-knowledge-base-web-page-element-view subscribe="auth" lang="de" entry-point-url="${this.entryPointUrl}" value="bedienstete/bibliothek/buch-ausleihen" text="Ein Buch ausleihen"></dbp-knowledge-base-web-page-element-view> + <dbp-knowledge-base-web-page-element-view + subscribe="auth" + lang="de" + entry-point-url="${this.entryPointUrl}" + value="bedienstete/bibliothek/buch-ausleihen" + text="Ein Buch ausleihen"></dbp-knowledge-base-web-page-element-view> </div> <div class="container"> <h2 class="subtitle">Englisch</h2> <p>A first step</p> - <dbp-knowledge-base-web-page-element-view subscribe="auth" lang="en" entry-point-url="${this.entryPointUrl}" value="bedienstete/bibliothek/buch-ausleihen" text="Borrow a book"></dbp-knowledge-base-web-page-element-view> + <dbp-knowledge-base-web-page-element-view + subscribe="auth" + lang="en" + entry-point-url="${this.entryPointUrl}" + value="bedienstete/bibliothek/buch-ausleihen" + text="Borrow a book"></dbp-knowledge-base-web-page-element-view> </div> - <hr> + <hr /> <div class="container"> <p>mit Text in der WebComponent:</p> - <dbp-knowledge-base-web-page-element-view subscribe="auth" lang="${this.lang}" value="abc/def/xyz" text="FAQ"></dbp-knowledge-base-web-page-element-view> + <dbp-knowledge-base-web-page-element-view + subscribe="auth" + lang="${this.lang}" + value="abc/def/xyz" + text="FAQ"></dbp-knowledge-base-web-page-element-view> </div> - <hr> + <hr /> <div class="container"> <p>ohne Text in der WebComponent:</p> Kontaktieren Sie uns unter... - <dbp-knowledge-base-web-page-element-view subscribe="auth" class="opt" lang="${this.lang}" value="abc/def/klm"></dbp-knowledge-base-web-page-element-view> + <dbp-knowledge-base-web-page-element-view + subscribe="auth" + class="opt" + lang="${this.lang}" + value="abc/def/klm"></dbp-knowledge-base-web-page-element-view> </div> </section> `; } } -commonUtils.defineCustomElement('dbp-knowledge-base-web-page-element-view-demo', KnowledgeBaseWebPageElementViewDemo); +commonUtils.defineCustomElement( + 'dbp-knowledge-base-web-page-element-view-demo', + KnowledgeBaseWebPageElementViewDemo +); diff --git a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view.js b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view.js index c1220dcf8b105d5d02ca807b9592cd0a8bc18fac..321ce0003063925c21d8eb6d68e3ed6f5478fd43 100644 --- a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view.js +++ b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view.js @@ -1,4 +1,7 @@ -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {KnowledgeBaseWebPageElementView} from './knowledge-base-web-page-element-view.js'; -commonUtils.defineCustomElement('dbp-knowledge-base-web-page-element-view', KnowledgeBaseWebPageElementView); +commonUtils.defineCustomElement( + 'dbp-knowledge-base-web-page-element-view', + KnowledgeBaseWebPageElementView +); diff --git a/packages/knowledge-base-web-page-element-view/src/i18n.js b/packages/knowledge-base-web-page-element-view/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/knowledge-base-web-page-element-view/src/i18n.js +++ b/packages/knowledge-base-web-page-element-view/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/knowledge-base-web-page-element-view/src/i18n/de/translation.json b/packages/knowledge-base-web-page-element-view/src/i18n/de/translation.json index 6e81531dca5285b89ec941d0a30b28d611839b00..4320b7e0366c65df53344a5d7817b42b3a812113 100644 --- a/packages/knowledge-base-web-page-element-view/src/i18n/de/translation.json +++ b/packages/knowledge-base-web-page-element-view/src/i18n/de/translation.json @@ -1,7 +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" + "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/knowledge-base-web-page-element-view/src/i18n/en/translation.json b/packages/knowledge-base-web-page-element-view/src/i18n/en/translation.json index 05eb31df511ec6c271e18d96dd2bdd94045f7170..4498be0a091751841348859c75071cdbd1abe0de 100644 --- a/packages/knowledge-base-web-page-element-view/src/i18n/en/translation.json +++ b/packages/knowledge-base-web-page-element-view/src/i18n/en/translation.json @@ -1,7 +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" + "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/knowledge-base-web-page-element-view/src/index.js b/packages/knowledge-base-web-page-element-view/src/index.js index 2d9635ee535e71cb695e5591b142884d1f4ba4c0..c45684e3aa3ef04340b4b59cfed377be20535fde 100644 --- a/packages/knowledge-base-web-page-element-view/src/index.js +++ b/packages/knowledge-base-web-page-element-view/src/index.js @@ -1,3 +1,3 @@ import {KnowledgeBaseWebPageElementView} from './knowledge-base-web-page-element-view.js'; -export {KnowledgeBaseWebPageElementView}; \ No newline at end of file +export {KnowledgeBaseWebPageElementView}; diff --git a/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js b/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js index 45b0655942f1bf47b72273283b9d66ba44639c30..0ea6ad618e106344683b4df748bb60996f3404ca 100644 --- a/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js +++ b/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js @@ -2,9 +2,9 @@ import {createInstance} from './i18n'; import {html} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {MiniSpinner} from '@dbp-toolkit/common'; -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; /** * KnowledgeBaseWebPageElementView web component @@ -18,8 +18,10 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter this.html = ''; this.entryPointUrl = ''; this.error = ''; - this.eyeClose = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA1ElEQVQ4ja3SMU5CURCF4c+ejpiILe5DZAGyASuJS5CKEoMGKhdAwWKgMkriKjQWFkAkBizgmckNPEgeJ7nVuee/M3eGI2mCehFAHZ/Hgtygizd84wsjPOHsEMgUqx1njvtd4R7uAmSIMipo4SeAHtLwdTCbG8gHLsOdVlJN9LwEY4nSFsh5AhhHwGtinoY/ySDlPEAjMbvByyDDvBbgOZi/eNxUkrUTp9NJw3CCNhbJS0vcBshgWzjqAn28W899Zr1U1dBObR8kT9nGXhWFTIoA/vUHQydS/iUcHx4AAAAASUVORK5CYII='; - this.eyeOpen = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA5UlEQVQ4jc3SvS7EURAF8B+JioSsCokHUFgNiWewQqvzICRew2v4WLFUnoNS/msrazUaFOYm12RlVeIkk9ycM2fmztzLf8U02tiPaAc3EbM4Rh8fKfo4wdxP5nXcV4YhLnGO54p/wEY2b6akHhYqfR7dVHyriMt4qsQRWtiNaw+wFwWHaaQlcc161l4UblIyXKTcM7hL5FUk14tsgsvNumIhb2NG6ISxiXMrtJI3wErZwyHeK/E2DAWLuKn0F2xLOEgdRriOeK34sc9YsIpT37dd4hFHvj7bRMxElw52sIap3xj/Hp9rzGFBhiMSxAAAAABJRU5ErkJggg=='; + this.eyeClose = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA1ElEQVQ4ja3SMU5CURCF4c+ejpiILe5DZAGyASuJS5CKEoMGKhdAwWKgMkriKjQWFkAkBizgmckNPEgeJ7nVuee/M3eGI2mCehFAHZ/Hgtygizd84wsjPOHsEMgUqx1njvtd4R7uAmSIMipo4SeAHtLwdTCbG8gHLsOdVlJN9LwEY4nSFsh5AhhHwGtinoY/ySDlPEAjMbvByyDDvBbgOZi/eNxUkrUTp9NJw3CCNhbJS0vcBshgWzjqAn28W899Zr1U1dBObR8kT9nGXhWFTIoA/vUHQydS/iUcHx4AAAAASUVORK5CYII='; + this.eyeOpen = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA5UlEQVQ4jc3SvS7EURAF8B+JioSsCokHUFgNiWewQqvzICRew2v4WLFUnoNS/msrazUaFOYm12RlVeIkk9ycM2fmztzLf8U02tiPaAc3EbM4Rh8fKfo4wdxP5nXcV4YhLnGO54p/wEY2b6akHhYqfR7dVHyriMt4qsQRWtiNaw+wFwWHaaQlcc161l4UblIyXKTcM7hL5FUk14tsgsvNumIhb2NG6ISxiXMrtJI3wErZwyHeK/E2DAWLuKn0F2xLOEgdRriOeK34sc9YsIpT37dd4hFHvj7bRMxElw52sIap3xj/Hp9rzGFBhiMSxAAAAABJRU5ErkJggg=='; //this.css = 'kb.css'; this.text = ''; this.class = ''; @@ -28,12 +30,14 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter static get scopedElements() { return { - 'dbp-mini-spinner': MiniSpinner, + 'dbp-mini-spinner': MiniSpinner, }; } _(selector) { - return this.shadowRoot === null ? this.querySelector(selector) : this.shadowRoot.querySelector(selector); + return this.shadowRoot === null + ? this.querySelector(selector) + : this.shadowRoot.querySelector(selector); } /** @@ -41,15 +45,15 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter */ static get properties() { return { - lang: { type: String }, - value: { type: String }, - html: { type: String, attribute: false }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - id: { type: String, attribute: false}, - error: { type: String, attribute: false}, + lang: {type: String}, + value: {type: String}, + html: {type: String, attribute: false}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + id: {type: String, attribute: false}, + error: {type: String, attribute: false}, //css: { type: String }, - text: { type: String }, - auth: { type: Object }, + text: {type: String}, + auth: {type: Object}, }; } @@ -59,64 +63,82 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter loadWebPageElement() { const i18n = this._i18n; - if (this.auth.token === undefined || this.auth.token === "") { + if (this.auth.token === undefined || this.auth.token === '') { return; } // sadly there there is no entity url without "collectionOperations" in entity KnowledgeBaseWebPageElement! - const apiUrl = this.entryPointUrl + "/web_page_elements/knowledge_base_web_page_elements/" + + const apiUrl = + this.entryPointUrl + + '/web_page_elements/knowledge_base_web_page_elements/' + encodeURIComponent(commonUtils.base64EncodeUnicode(encodeURIComponent(this.value))) + - "?lang=" + encodeURIComponent(this.lang); + '?lang=' + + encodeURIComponent(this.lang); var that = this; fetch(apiUrl, { headers: { 'Content-Type': 'application/ld+json', - 'Authorization': 'Bearer ' + this.auth.token, + Authorization: 'Bearer ' + this.auth.token, }, }) - .then(function (res) { - if (!res.ok) { - let status_msg; - switch (res.status) { - case 403: - status_msg = i18n.t('is-forbidden'); - break; - case 404: - status_msg = i18n.t('was-not-found'); - break; - case 500: - status_msg = i18n.t('troubled-server'); - break; - default: - status_msg = i18n.t('unknown-problems'); + .then(function (res) { + if (!res.ok) { + let status_msg; + switch (res.status) { + case 403: + status_msg = i18n.t('is-forbidden'); + break; + case 404: + status_msg = i18n.t('was-not-found'); + break; + case 500: + status_msg = i18n.t('troubled-server'); + break; + default: + status_msg = i18n.t('unknown-problems'); + } + const error_head = i18n.t('error-head'); + that.error = html` + <p> + ${error_head} " + <b>${that.value}</b> + " ${status_msg} (${res.status}). + </p> + `; + that.html = ''; + throw new Error( + 'HTTP ' + + error_head + + ' ' + + that.value + + ' ' + + status_msg + + ', status = ' + + res.status + ); } - const error_head = i18n.t('error-head'); - that.error = html`<p>${error_head} "<b>${that.value}</b>" ${status_msg} (${res.status}).</p>`; - that.html = ""; - throw new Error('HTTP ' + error_head + ' ' + that.value + ' ' + status_msg + ', status = ' + res.status); - } - return res.json(); - }) - .then(webPageElement => { - if (webPageElement !== undefined && webPageElement.text !== undefined) { - that.html = webPageElement.text; - } - }) - // catch e.g. 404 errors - .catch(); + return res.json(); + }) + .then((webPageElement) => { + if (webPageElement !== undefined && webPageElement.text !== undefined) { + that.html = webPageElement.text; + } + }) + // catch e.g. 404 errors + .catch(); } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } - switch(propName) { - case "lang": - case "value": - case "entry-point-url": { + switch (propName) { + case 'lang': + case 'value': + case 'entry-point-url': { this.html = ''; const img = this._('#A2'); if (img !== null) { @@ -128,7 +150,7 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter } break; } - case "text": + case 'text': this.class = this.text !== '' ? 'has-text' : ''; break; } @@ -149,7 +171,7 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter img.src = this.eyeOpen; } if (this.html === '' && div.style.display !== 'none') { - this.html = "<dbp-mini-spinner></dbp-mini-spinner>"; + this.html = '<dbp-mini-spinner></dbp-mini-spinner>'; this.loadWebPageElement(); } } @@ -164,14 +186,18 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter margin: var(--KBMargin, 0); padding: var(--KBPadding, 0); } - span.has-text img {margin-left: 5px} - span.with-pointer { cursor: pointer; } + span.has-text img { + margin-left: 5px; + } + span.with-pointer { + cursor: pointer; + } </style> - <span class="with-pointer ${this.class}" @click="${this.toggle}">${this.text}<img src="${this.eyeOpen}" id="A2" alt="open/close"></span> - <div class='kb' id="A1"> - ${unsafeHTML(this.html)} - ${this.error} - </div> + <span class="with-pointer ${this.class}" @click="${this.toggle}"> + ${this.text} + <img src="${this.eyeOpen}" id="A2" alt="open/close" /> + </span> + <div class="kb" id="A1">${unsafeHTML(this.html)} ${this.error}</div> `; } -} \ No newline at end of file +} diff --git a/packages/knowledge-base-web-page-element-view/test/unit.js b/packages/knowledge-base-web-page-element-view/test/unit.js index acd3ddd8f6ce87555d5120d03ead5498beac970d..49c42dcbff861ec69f2b138c2168c92911e15298 100644 --- a/packages/knowledge-base-web-page-element-view/test/unit.js +++ b/packages/knowledge-base-web-page-element-view/test/unit.js @@ -4,37 +4,37 @@ import '../src/dbp-knowledge-base-web-page-element-view.js'; import '../src/dbp-knowledge-base-web-page-element-view-demo.js'; suite('dbp-knowledge-base-web-page-element-view basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-knowledge-base-web-page-element-view'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-knowledge-base-web-page-element-view'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); suite('dbp-knowledge-base-web-page-element-view demo', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-knowledge-base-web-page-element-view-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-knowledge-base-web-page-element-view-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/matomo/.eslintrc.json b/packages/matomo/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/matomo/.eslintrc.json +++ b/packages/matomo/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/matomo/.prettierignore b/packages/matomo/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/matomo/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/matomo/.prettierrc.json b/packages/matomo/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/matomo/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/matomo/i18next-scanner.config.js b/packages/matomo/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/matomo/i18next-scanner.config.js +++ b/packages/matomo/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/matomo/package.json b/packages/matomo/package.json index 629686900b13f8ccb29ad629acbe57ddf12d592f..1ca790b3fa33c1dc01117393fa6bda1badd530dc 100644 --- a/packages/matomo/package.json +++ b/packages/matomo/package.json @@ -1,57 +1,61 @@ { - "name": "@dbp-toolkit/matomo", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/matomo", - "version": "0.2.4", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/matomo" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "lit": "^2.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": "rollup -c --watch", - "watch-local": "yarn run watch", - "watch-dev": "rollup -c --watch --environment BUILD:development", - "test": "rollup -c --environment BUILD:test && karma start --singleRun", - "lint": "eslint ." - } + "name": "@dbp-toolkit/matomo", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/matomo", + "version": "0.2.4", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/matomo" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "lit": "^2.0.0" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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": "rollup -c --watch", + "watch-local": "yarn run watch", + "watch-dev": "rollup -c --watch --environment BUILD:development", + "test": "rollup -c --environment BUILD:test && karma start --singleRun", + "lint": "eslint ." + } } diff --git a/packages/matomo/rollup.config.js b/packages/matomo/rollup.config.js index 3f0bd71106cd7e6b0a8ad91c5d338050f11d1dea..eea210c90537271471f5665033620c397d01a702 100644 --- a/packages/matomo/rollup.config.js +++ b/packages/matomo/rollup.config.js @@ -2,18 +2,18 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url"; +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; -import emitEJS from 'rollup-plugin-emit-ejs' +import emitEJS from 'rollup-plugin-emit-ejs'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); -const matomoUrl = "https://analytics.tugraz.at/"; +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); +const matomoUrl = 'https://analytics.tugraz.at/'; const matomoSiteId = 131; function getBuildInfo() { @@ -26,7 +26,7 @@ function getBuildInfo() { let parsed = url.parse(remote); // convert git urls if (parsed.protocol === null) { - parsed = url.parse('git://' + remote.replace(":", "/")); + parsed = url.parse('git://' + remote.replace(':', '/')); parsed.protocol = 'https:'; } let newPath = parsed.path.slice(0, parsed.path.lastIndexOf('.')); @@ -36,23 +36,26 @@ function getBuildInfo() { info: commit, url: newUrl, time: new Date().toISOString(), - env: build - } + env: build, + }; } export default (async () => { return { - input: (build != 'test') ? ['src/dbp-matomo.js', 'src/dbp-matomo-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-matomo.js', 'src/dbp-matomo-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), emitEJS({ src: 'assets', @@ -68,29 +71,32 @@ export default (async () => { environment: build, matomoUrl: matomoUrl, matomoSiteId: matomoSiteId, - buildInfo: getBuildInfo() - } + buildInfo: getBuildInfo(), + }, }), resolve(), commonjs(), url({ limit: 0, - include: [ - await getPackagePath('select2', '**/*.css'), - ], + include: [await getPackagePath('select2', '**/*.css')], emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, - {src: 'assets/favicon.ico', dest:'dist'}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, + {src: 'assets/favicon.ico', dest: 'dist'}, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; })(); diff --git a/packages/matomo/src/dbp-matomo-demo.js b/packages/matomo/src/dbp-matomo-demo.js index 476682adca65b3af07c2f82baa035bc560eafa33..187486142486a7aac6f8ae541cf64a9d965c9b12 100644 --- a/packages/matomo/src/dbp-matomo-demo.js +++ b/packages/matomo/src/dbp-matomo-demo.js @@ -5,11 +5,9 @@ import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {MatomoElement} from './matomo'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; - +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; export class MatomoDemo extends ScopedElementsMixin(DBPLitElement) { - constructor() { super(); this._i18n = createInstance(); @@ -31,17 +29,17 @@ export class MatomoDemo extends ScopedElementsMixin(DBPLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - matomoUrl: { type: String, attribute: "matomo-url" }, - matomoSiteId: { type: Number, attribute: "matomo-site-id" }, - noAuth: { type: Boolean, attribute: 'no-auth' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + matomoUrl: {type: String, attribute: 'matomo-url'}, + matomoSiteId: {type: Number, attribute: 'matomo-site-id'}, + noAuth: {type: Boolean, attribute: 'no-auth'}, }; } update(changedProperties) { - changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + changedProperties.forEach((oldValue, propName) => { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -50,7 +48,7 @@ export class MatomoDemo extends ScopedElementsMixin(DBPLitElement) { } track(action, message) { - this.sendSetPropertyEvent('analytics-event', {'category': action, 'action': message}); + this.sendSetPropertyEvent('analytics-event', {category: action, action: message}); } clickMe() { @@ -65,38 +63,54 @@ export class MatomoDemo extends ScopedElementsMixin(DBPLitElement) { commonStyles.getThemeCSS(), commonStyles.getGeneralCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em; padding-left:20px;} - ` + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + padding-left: 20px; + } + `, ]; } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button>` : html` - <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" - url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" - client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> - <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> - </div> - `; + return this.noAuth + ? html` + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + ` + : html` + <div class="container"> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + url="https://auth-dev.tugraz.at/auth" + realm="tugraz-vpu" + client-id="auth-dev-mw-frontend-local" + try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + </div> + `; } render() { - return html` <section class="section"> <div class="container"> <h1 class="title">Matomo-Demo</h1> </div> <div class="container"> - ${ this.getAuthComponentHtml() } - <dbp-matomo endpoint="${this.matomoUrl}" site-id="${this.matomoSiteId}"></dbp-matomo> + ${this.getAuthComponentHtml()} + <dbp-matomo + endpoint="${this.matomoUrl}" + site-id="${this.matomoSiteId}"></dbp-matomo> </div> <div class="container"> <p>Click this button (and watch the network traffic) ...</p> - <p><input type="button" value="click me" @click="${this.clickMe}"></p> - </div> + <p><input type="button" value="click me" @click="${this.clickMe}" /></p> + </div> </section> `; } diff --git a/packages/matomo/src/demo.js b/packages/matomo/src/demo.js index 08dfd041306a9c2f8ed1427b01e2aa0a425b16ae..2b051a141d0ef21b7bc1b0a50ebf63232cd60c8a 100644 --- a/packages/matomo/src/demo.js +++ b/packages/matomo/src/demo.js @@ -1 +1 @@ -import './dbp-matomo-demo.js'; \ No newline at end of file +import './dbp-matomo-demo.js'; diff --git a/packages/matomo/src/i18n.js b/packages/matomo/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/matomo/src/i18n.js +++ b/packages/matomo/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/matomo/src/index.js b/packages/matomo/src/index.js index fca225961b2d2d8fd8a91b463f5d57fe8912752a..c707de5291fab1166898de66d0882670f813d2ce 100644 --- a/packages/matomo/src/index.js +++ b/packages/matomo/src/index.js @@ -1,3 +1,3 @@ import {Matomo} from './matomo.js'; -export {Matomo}; \ No newline at end of file +export {Matomo}; diff --git a/packages/matomo/src/matomo.js b/packages/matomo/src/matomo.js index fd5ab2938ab544f762bca2ddd779f20b55745621..ba7bb7188a033cbbc18a80d2f5a4b7a6c866e893 100644 --- a/packages/matomo/src/matomo.js +++ b/packages/matomo/src/matomo.js @@ -1,8 +1,7 @@ import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; -import {LoginStatus} from "@dbp-toolkit/auth/src/util"; +import {LoginStatus} from '@dbp-toolkit/auth/src/util'; export class MatomoElement extends DBPLitElement { - constructor() { super(); this.endpoint = ''; @@ -15,15 +14,14 @@ export class MatomoElement extends DBPLitElement { this.loginStatus = ''; } - static get properties() { return { ...super.properties, - endpoint: { type: String }, - siteId: { type: String, attribute: 'site-id' }, - gitInfo: { type: String, attribute: 'git-info' }, - auth: { type: Object }, - analyticsEvent: { type: Object, attribute: 'analytics-event' }, + endpoint: {type: String}, + siteId: {type: String, attribute: 'site-id'}, + gitInfo: {type: String, attribute: 'git-info'}, + auth: {type: Object}, + analyticsEvent: {type: Object, attribute: 'analytics-event'}, }; } @@ -31,33 +29,47 @@ export class MatomoElement extends DBPLitElement { changedProperties.forEach((oldValue, propName) => { switch (propName) { case 'auth': - { - const loginStatus = this.auth['login-status']; + { + const loginStatus = this.auth['login-status']; - if (this.loginStatus !== loginStatus) { - this.setupMatomo(loginStatus === LoginStatus.LOGGED_IN); - this.loginStatus = loginStatus; + if (this.loginStatus !== loginStatus) { + this.setupMatomo(loginStatus === LoginStatus.LOGGED_IN); + this.loginStatus = loginStatus; + } } - } - break; + break; case 'analyticsEvent': - { - // ignore analyticsEvent without data - if (this.analyticsEvent.category === undefined && this.analyticsEvent.message === undefined) { - break; + { + // ignore analyticsEvent without data + if ( + this.analyticsEvent.category === undefined && + this.analyticsEvent.message === undefined + ) { + break; + } + console.log( + 'MatomoElement(' + + this.isRunning + + ') analyticsEvent: ' + + this.analyticsEvent.action + + ', ' + + this.analyticsEvent.message + ); + const event = [ + 'trackEvent', + this.analyticsEvent.category, + this.analyticsEvent.action, + this.analyticsEvent.name, + this.analyticsEvent.value, + ]; + + if (this.isRunning) { + this.pushEvent(event); + } else { + this.lastEvent = event; + } } - console.log('MatomoElement(' + this.isRunning + ') analyticsEvent: ' + - this.analyticsEvent.action + ', ' + this.analyticsEvent.message); - const event = ['trackEvent', this.analyticsEvent.category, this.analyticsEvent.action, - this.analyticsEvent.name, this.analyticsEvent.value]; - - if (this.isRunning) { - this.pushEvent(event); - } else { - this.lastEvent = event; - } - } - break; + break; } }); @@ -69,7 +81,7 @@ export class MatomoElement extends DBPLitElement { } setupMatomo(loggedIn) { - if (loggedIn && ! this.isRunning) { + if (loggedIn && !this.isRunning) { if (this.siteId === '') { console.log('site id missing, skipping matomo...'); return; @@ -80,7 +92,7 @@ export class MatomoElement extends DBPLitElement { } console.log('add matomo...'); - this.pushEvent(['setCustomVariable', 1, "GitCommit", this.gitInfo, "visit"]); + this.pushEvent(['setCustomVariable', 1, 'GitCommit', this.gitInfo, 'visit']); this.pushEvent(['enableHeartBeatTimer']); this.pushEvent(['disableCookies']); this.pushEvent(['trackPageView']); @@ -89,7 +101,7 @@ export class MatomoElement extends DBPLitElement { const that = this; (function (endpoint, siteId) { - that.pushEvent(['setTrackerUrl', endpoint+'matomo.php']); + that.pushEvent(['setTrackerUrl', endpoint + 'matomo.php']); that.pushEvent(['setSiteId', siteId]); var g = document.createElement('script'); @@ -102,7 +114,7 @@ export class MatomoElement extends DBPLitElement { })(this.endpoint, this.siteId); // track changed locations - window.addEventListener('locationchanged', function(e) { + window.addEventListener('locationchanged', function (e) { that.pushEvent(['setReferrerUrl', e.detail.referrerUrl]); that.pushEvent(['setCustomUrl', location.href]); // that.pushEvent(['setDocumentTitle', '']); @@ -116,24 +128,27 @@ export class MatomoElement extends DBPLitElement { }); // track errors - window.addEventListener('error', function(e) { - that.pushEvent(['trackEvent', 'Error', e.error ? - e.error.message + '\n' + e.error.stack : e.message]); + window.addEventListener('error', function (e) { + that.pushEvent([ + 'trackEvent', + 'Error', + e.error ? e.error.message + '\n' + e.error.stack : e.message, + ]); }); - window.addEventListener('unhandledrejection', function(e) { + window.addEventListener('unhandledrejection', function (e) { let name = e.reason; // TypeError objects have no toJSON() method, so we can't serialize them by themselves if (e.reason instanceof TypeError) { const error = e.reason; name = { - 'message': error.message, - 'name': error.name, - 'fileName': error.fileName, - 'lineNumber': error.lineNumber, - 'columnNumber': error.columnNumber, - 'stack': error.stack, + message: error.message, + name: error.name, + fileName: error.fileName, + lineNumber: error.lineNumber, + columnNumber: error.columnNumber, + stack: error.stack, }; } @@ -142,13 +157,20 @@ export class MatomoElement extends DBPLitElement { this.isRunning = true; if (this.lastEvent.length > 0) { - console.log('MatomoElement* (' + this.isRunning + '): ' + this.lastEvent[1] + ', ' + this.lastEvent[2]); + console.log( + 'MatomoElement* (' + + this.isRunning + + '): ' + + this.lastEvent[1] + + ', ' + + this.lastEvent[2] + ); that.pushEvent(this.lastEvent); this.lastEvent = []; } return; } - if (! loggedIn && this.isRunning) { + if (!loggedIn && this.isRunning) { // TODO: remove those event listeners console.log('remove matomo...'); this.isRunning = false; diff --git a/packages/matomo/test/unit.js b/packages/matomo/test/unit.js index 7022483461346078ffdd27819549f6dbcc363807..8918a21b95ffd6b73ee470683d81e1d070e5bb43 100644 --- a/packages/matomo/test/unit.js +++ b/packages/matomo/test/unit.js @@ -3,19 +3,18 @@ import '../src/dbp-matomo'; suite('dbp-matomo', () => { let node; - + setup(async () => { - node = document.createElement('dbp-matomo'); - document.body.appendChild(node); - await node.updateComplete; + node = document.createElement('dbp-matomo'); + document.body.appendChild(node); + await node.updateComplete; }); - + teardown(() => { - node.remove(); + node.remove(); }); - + test('should render', () => { - assert.isNotNull(node.shadowRoot); + assert.isNotNull(node.shadowRoot); }); - }); - \ No newline at end of file +}); diff --git a/packages/notification/.eslintrc.json b/packages/notification/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/notification/.eslintrc.json +++ b/packages/notification/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/notification/.prettierignore b/packages/notification/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/notification/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/notification/.prettierrc.json b/packages/notification/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/notification/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/notification/i18next-scanner.config.js b/packages/notification/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/notification/i18next-scanner.config.js +++ b/packages/notification/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/notification/package.json b/packages/notification/package.json index 2cc8d46447c47f4a3671c5983ed383f460bbc657..3dba9201fecaeb28c64dcf08500c334178d9822c 100644 --- a/packages/notification/package.json +++ b/packages/notification/package.json @@ -1,56 +1,60 @@ { - "name": "@dbp-toolkit/notification", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/notification", - "version": "0.2.3", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/notification" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.0.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "lit": "^2.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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/notification", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/notification", + "version": "0.2.3", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/notification" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.0.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "lit": "^2.0.0" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/notification/rollup.config.js b/packages/notification/rollup.config.js index db5e077faed8e6046b809f927b31d8d6b832741a..30325ee97ecf8f849c01d56851ac6feafbcc39b2 100644 --- a/packages/notification/rollup.config.js +++ b/packages/notification/rollup.config.js @@ -2,27 +2,30 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url"; +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default { - input: (build != 'test') ? ['src/dbp-notification.js', 'src/dbp-notification-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-notification.js', 'src/dbp-notification-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), @@ -30,15 +33,17 @@ export default { url({ limit: 0, emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, {src: 'assets/favicon.ico', dest: 'dist'}, - ] + ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; diff --git a/packages/notification/src/dbp-notification-demo.js b/packages/notification/src/dbp-notification-demo.js index b91559495cf6ab6c942514b7b8d8e275a2318644..7470f53845fa03d71f719536c47242b7e0277932 100644 --- a/packages/notification/src/dbp-notification-demo.js +++ b/packages/notification/src/dbp-notification-demo.js @@ -4,7 +4,7 @@ import {css, html, LitElement} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {Notification} from './notification.js'; import * as commonUtils from '@dbp-toolkit/common/utils'; -import * as commonStyles from "@dbp-toolkit/common/styles"; +import * as commonStyles from '@dbp-toolkit/common/styles'; export class NotificationDemo extends ScopedElementsMixin(LitElement) { constructor() { @@ -15,25 +15,25 @@ export class NotificationDemo extends ScopedElementsMixin(LitElement) { static get scopedElements() { return { - 'dbp-notification': Notification, + 'dbp-notification': Notification, }; - } + } static get properties() { return { - lang: { type: String }, + lang: {type: String}, }; } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { - this._i18n.changeLanguage(this.lang); - } - }); + if (propName === 'lang') { + this._i18n.changeLanguage(this.lang); + } + }); - super.update(changedProperties); - } + super.update(changedProperties); + } static get styles() { // language=css @@ -55,7 +55,9 @@ export class NotificationDemo extends ScopedElementsMixin(LitElement) { <div class="container"> <div class="columns is-vcentered"> <div class="column"> - <button id="send-button" @click="${this.send}" class="button">${i18n.t('send')}</button> + <button id="send-button" @click="${this.send}" class="button"> + ${i18n.t('send')} + </button> </div> </div> </div> @@ -67,12 +69,12 @@ export class NotificationDemo extends ScopedElementsMixin(LitElement) { } send() { - const types = ["primary", "info", "success", "danger", "warning"]; + const types = ['primary', 'info', 'success', 'danger', 'warning']; notify({ - "summary": "Item deleted", - "body": `Item ${Math.random().toString(36).substring(7)} foo was deleted!`, - "type": types[Math.floor(Math.random() * types.length)], - "timeout": 0, + summary: 'Item deleted', + body: `Item ${Math.random().toString(36).substring(7)} foo was deleted!`, + type: types[Math.floor(Math.random() * types.length)], + timeout: 0, }); } } diff --git a/packages/notification/src/i18n.js b/packages/notification/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/notification/src/i18n.js +++ b/packages/notification/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/notification/src/i18n/de/translation.json b/packages/notification/src/i18n/de/translation.json index 76141362384a4cdfe114fb47b37b91f26d9912f2..cc82626e99881d6bb523410ff5f1977e27edcd6b 100644 --- a/packages/notification/src/i18n/de/translation.json +++ b/packages/notification/src/i18n/de/translation.json @@ -1,3 +1,3 @@ { - "send": "senden" + "send": "senden" } diff --git a/packages/notification/src/i18n/en/translation.json b/packages/notification/src/i18n/en/translation.json index 4e26b222a97c4af68049bf386d36b2d4fab88a88..cf59c597c54e13ce2a0cca4e5669682b73c279df 100644 --- a/packages/notification/src/i18n/en/translation.json +++ b/packages/notification/src/i18n/en/translation.json @@ -1,3 +1,3 @@ { - "send": "send" + "send": "send" } diff --git a/packages/notification/src/index.js b/packages/notification/src/index.js index cb7a0c58bff5391b90a2dbafcd03c148a8d80b1a..490a60253559176493b2b25757db4b08c3f6f3df 100644 --- a/packages/notification/src/index.js +++ b/packages/notification/src/index.js @@ -1,3 +1,3 @@ import {Notification} from './notification.js'; -export {Notification}; \ No newline at end of file +export {Notification}; diff --git a/packages/notification/src/notification.js b/packages/notification/src/notification.js index db9bda9df0950f645cec41a0bfbb583737358a4d..98296b8323fdfcc22058ad42b1e4c11d5cb238d2 100644 --- a/packages/notification/src/notification.js +++ b/packages/notification/src/notification.js @@ -20,7 +20,7 @@ export class Notification extends DBPLitElement { static get properties() { return { ...super.properties, - lang: { type: String }, + lang: {type: String}, }; } @@ -28,23 +28,24 @@ export class Notification extends DBPLitElement { super.connectedCallback(); const that = this; - window.addEventListener("dbp-notification-send", (e) => { + window.addEventListener('dbp-notification-send', (e) => { if (typeof e.detail === 'undefined') { return; } - that.notificationBlock = that._("#notification"); + that.notificationBlock = that._('#notification'); const notificationId = `notification-${createUUID()}`; - const type = typeof e.detail.type !== 'undefined' ? e.detail.type : "info"; - const body = typeof e.detail.body !== 'undefined' ? e.detail.body : ""; - const summary = typeof e.detail.summary !== 'undefined' ? e.detail.summary : ""; + const type = typeof e.detail.type !== 'undefined' ? e.detail.type : 'info'; + const body = typeof e.detail.body !== 'undefined' ? e.detail.body : ''; + const summary = typeof e.detail.summary !== 'undefined' ? e.detail.summary : ''; const timeout = typeof e.detail.timeout !== 'undefined' ? e.detail.timeout : 0; const icon = typeof e.detail.icon !== 'undefined' ? e.detail.icon : ''; - const iconHTML = icon !== '' ? `<dbp-icon name="${icon}"></dbp-icon>` : ""; - const summaryHTML = summary !== "" ? `<h3>${summary}</h3>` : ""; + const iconHTML = icon !== '' ? `<dbp-icon name="${icon}"></dbp-icon>` : ''; + const summaryHTML = summary !== '' ? `<h3>${summary}</h3>` : ''; - that.notificationBlock.innerHTML = ` + that.notificationBlock.innerHTML = + ` <div id="${notificationId}" class="notification is-${type}"> <button id="${notificationId}-button" onclick="parentNode.parentNode.removeChild(parentNode)" class="delete"></button> ${summaryHTML} @@ -89,10 +90,11 @@ export class Notification extends DBPLitElement { margin-bottom: 3px; } - .delete, .modal-close { + .delete, + .modal-close { -moz-appearance: none; -webkit-appearance: none; - background-color: rgba(10,10,10,.2); + background-color: rgba(10, 10, 10, 0.2); border: none; border-radius: 290486px; cursor: pointer; @@ -112,46 +114,62 @@ export class Notification extends DBPLitElement { width: 20px; } - .delete::before, .modal-close::before, .delete::after, .modal-close::after { + .delete::before, + .modal-close::before, + .delete::after, + .modal-close::after { background-color: var(--dbp-base); color: var(--dbp-text); - content: ""; + content: ''; display: block; left: 50%; position: absolute; top: 50%; -webkit-transform: translateX(-50%) translateY(-50%) rotate(45deg); - transform: translateX(-50%) translateY(-50%) rotate(45deg); + transform: translateX(-50%) translateY(-50%) rotate(45deg); -webkit-transform-origin: center center; - transform-origin: center center; + transform-origin: center center; } - .delete::before, .modal-close::before { + .delete::before, + .modal-close::before { height: 2px; width: 50%; } - .delete::after, .modal-close::after { + .delete::after, + .modal-close::after { height: 50%; width: 2px; } - .delete:hover, .modal-close:hover, .delete:focus, .modal-close:focus { + .delete:hover, + .modal-close:hover, + .delete:focus, + .modal-close:focus { background-color: rgba(10, 10, 10, 0.3); } - .delete:active, .modal-close:active { + .delete:active, + .modal-close:active { background-color: rgba(10, 10, 10, 0.4); } #notification { - position: fixed; top: 0; max-width: 500px; margin: 0.75em auto; left: 0; right: 0; z-index: 1000; padding: 0; + position: fixed; + top: 0; + max-width: 500px; + margin: 0.75em auto; + left: 0; + right: 0; + z-index: 1000; + padding: 0; } .notification h3 { margin: 0 0 3px 0; font: inherit; - font-weight: bold; + font-weight: bold; } `; } @@ -159,9 +177,8 @@ export class Notification extends DBPLitElement { render() { return html` <div class="columns"> - <div class="column" id="notification"> - </div> + <div class="column" id="notification"></div> </div> `; } -} \ No newline at end of file +} diff --git a/packages/notification/src/utils.js b/packages/notification/src/utils.js index 25e76d3eaecf590dabe58265949f4ef0fefbea23..fb9f71b8302e1f8f9c766c152a612474276c3420 100644 --- a/packages/notification/src/utils.js +++ b/packages/notification/src/utils.js @@ -1,11 +1,10 @@ export const createUUID = () => { let dt = new Date().getTime(); const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { - const r = (dt + Math.random()*16)%16 | 0; - dt = Math.floor(dt/16); - return (c==='x' ? r :(r&0x3|0x8)).toString(16); + const r = (dt + Math.random() * 16) % 16 | 0; + dt = Math.floor(dt / 16); + return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); }); return uuid; }; - diff --git a/packages/notification/test/unit.js b/packages/notification/test/unit.js index c38198654ae4b356be7765f9c25770e44e59fbc8..14018d3f3ab130f741d542b4458fa053d8c5fb11 100644 --- a/packages/notification/test/unit.js +++ b/packages/notification/test/unit.js @@ -3,19 +3,19 @@ import {assert} from '@esm-bundle/chai'; import '../src/dbp-notification'; suite('dbp-notification basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-notification'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-notification'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/organization-select/.eslintrc.json b/packages/organization-select/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/organization-select/.eslintrc.json +++ b/packages/organization-select/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/organization-select/.prettierignore b/packages/organization-select/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/organization-select/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/organization-select/.prettierrc.json b/packages/organization-select/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/organization-select/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/organization-select/i18next-scanner.config.js b/packages/organization-select/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/organization-select/i18next-scanner.config.js +++ b/packages/organization-select/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/organization-select/package.json b/packages/organization-select/package.json index c9a8289bbb0106a0ae73966b42145a770539ad6f..de00f7a5da4d80a805e6f933d08aa5bd025c007f 100644 --- a/packages/organization-select/package.json +++ b/packages/organization-select/package.json @@ -1,60 +1,64 @@ { - "name": "@dbp-toolkit/organization-select", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/organization-select", - "version": "0.2.3", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/organization-select" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-replace": "^3.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "jquery": "^3.4.1", - "lit": "^2.0.0", - "select2": "^4.0.10" - }, - "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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/organization-select", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/organization-select", + "version": "0.2.3", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/organization-select" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-replace": "^3.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "jquery": "^3.4.1", + "lit": "^2.0.0", + "select2": "^4.0.10" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/organization-select/rollup.config.js b/packages/organization-select/rollup.config.js index 277d22c2b1251e24a18ca4a16f79376b116651d3..19a8bc25efaa45236c79e096be0f088822e506bb 100644 --- a/packages/organization-select/rollup.config.js +++ b/packages/organization-select/rollup.config.js @@ -2,49 +2,55 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url" +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build != 'test') ? ['src/dbp-organization-select.js', 'src/dbp-organization-select-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-organization-select.js', 'src/dbp-organization-select-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), url({ limit: 0, - include: [ - await getPackagePath('select2', '**/*.css'), - ], + include: [await getPackagePath('select2', '**/*.css')], emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/organization-select/src/dbp-organization-select-demo.js b/packages/organization-select/src/dbp-organization-select-demo.js index e397c14f23f77bd74ce0c415ba98a0dcb56b1b8c..f40bab7e40887cf559b176d7ab5c6f67d0ade454 100644 --- a/packages/organization-select/src/dbp-organization-select-demo.js +++ b/packages/organization-select/src/dbp-organization-select-demo.js @@ -5,7 +5,7 @@ import {OrganizationSelect} from './organization-select.js'; import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; export class OrganizationSelectDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { @@ -18,23 +18,23 @@ export class OrganizationSelectDemo extends ScopedElementsMixin(DBPLitElement) { static get scopedElements() { return { - 'dbp-auth-keycloak': AuthKeycloak, - 'dbp-login-button': LoginButton, - 'dbp-organization-select': OrganizationSelect, + 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-login-button': LoginButton, + 'dbp-organization-select': OrganizationSelect, }; } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - noAuth: { type: Boolean, attribute: 'no-auth' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + noAuth: {type: Boolean, attribute: 'no-auth'}, }; } update(changedProperties) { - if (changedProperties.has("lang")) { + if (changedProperties.has('lang')) { this._i18n.changeLanguage(this.lang); } super.update(changedProperties); @@ -46,21 +46,35 @@ export class OrganizationSelectDemo extends ScopedElementsMixin(DBPLitElement) { commonStyles.getThemeCSS(), commonStyles.getGeneralCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} - ` + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } + `, ]; } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button>` : html` - <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" - url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" - client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> - <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> - </div> - `; + return this.noAuth + ? html` + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + ` + : html` + <div class="container"> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + url="https://auth-dev.tugraz.at/auth" + realm="tugraz-vpu" + client-id="auth-dev-mw-frontend-local" + try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + </div> + `; } render() { @@ -73,15 +87,29 @@ export class OrganizationSelectDemo extends ScopedElementsMixin(DBPLitElement) { <div class="container"> <form> <div class="field"> - <label class="label">All related organization of the current user</label> + <label class="label"> + All related organization of the current user + </label> <div class="control"> - <dbp-organization-select id="organization-select-all" subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-organization-select> + <dbp-organization-select + id="organization-select-all" + subscribe="auth" + lang="${this.lang}" + entry-point-url="${this + .entryPointUrl}"></dbp-organization-select> </div> </div> <div class="field"> - <label class="label">Organization where the current user is library-manager</label> + <label class="label"> + Organization where the current user is library-manager + </label> <div class="control"> - <dbp-organization-select id="organization-select-library-manager" subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" context="library-manager"></dbp-organization-select> + <dbp-organization-select + id="organization-select-library-manager" + subscribe="auth" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + context="library-manager"></dbp-organization-select> </div> </div> </form> diff --git a/packages/organization-select/src/i18n.js b/packages/organization-select/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/organization-select/src/i18n.js +++ b/packages/organization-select/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/organization-select/src/i18n/de/select2.js b/packages/organization-select/src/i18n/de/select2.js index a71ad054f22ec26020eb6ef47b9028819301f5a5..ef28f0baced16331b48a64da4c0674f963d83521 100644 --- a/packages/organization-select/src/i18n/de/select2.js +++ b/packages/organization-select/src/i18n/de/select2.js @@ -41,6 +41,6 @@ export default function () { }, removeAllItems: function () { return 'Auswahl aufheben'; - } + }, }; } diff --git a/packages/organization-select/src/i18n/de/translation.json b/packages/organization-select/src/i18n/de/translation.json index bcef063e83ed380940cbb466442734eb7aebb3e0..d62a3521c514dd5cf425af29a41be2a2d1b363fd 100644 --- a/packages/organization-select/src/i18n/de/translation.json +++ b/packages/organization-select/src/i18n/de/translation.json @@ -1,6 +1,6 @@ { - "select-organization": { - "placeholder": "Bitte wählen Sie ein Institut aus", - "loading": "Wird geladen..." - } + "select-organization": { + "placeholder": "Bitte wählen Sie ein Institut aus", + "loading": "Wird geladen..." + } } diff --git a/packages/organization-select/src/i18n/en/select2.js b/packages/organization-select/src/i18n/en/select2.js index 5fae9cf669886af2ac9920f90197a05726db1f35..81d70d7c2332d84e470ad4dfb43f2baf5a9e2a48 100644 --- a/packages/organization-select/src/i18n/en/select2.js +++ b/packages/organization-select/src/i18n/en/select2.js @@ -45,6 +45,6 @@ export default function () { }, removeAllItems: function () { return 'Remove selection'; - } + }, }; } diff --git a/packages/organization-select/src/i18n/en/translation.json b/packages/organization-select/src/i18n/en/translation.json index ff54432a4ec79b0d3232c3c9a2ab45348cc544f0..bbbf8f54e0e173e7cbe2580654b28a37ae81569c 100644 --- a/packages/organization-select/src/i18n/en/translation.json +++ b/packages/organization-select/src/i18n/en/translation.json @@ -1,6 +1,6 @@ { - "select-organization": { - "placeholder": "Please select an organization", - "loading": "Loading..." - } + "select-organization": { + "placeholder": "Please select an organization", + "loading": "Loading..." + } } diff --git a/packages/organization-select/src/index.js b/packages/organization-select/src/index.js index 8640eef1be32766f394585fe86abdc7dd6efec56..76dc69b4b27382f0bbbe8b4087c0e1e0e15e9780 100644 --- a/packages/organization-select/src/index.js +++ b/packages/organization-select/src/index.js @@ -1,3 +1,3 @@ import {OrganizationSelect} from './organization-select.js'; -export {OrganizationSelect}; \ No newline at end of file +export {OrganizationSelect}; diff --git a/packages/organization-select/src/organization-select.js b/packages/organization-select/src/organization-select.js index f069a90415340061a6d3dd969ecd797795ebf762..d28a5c696abc90b42361cb72ccd3dae3e8e448a9 100644 --- a/packages/organization-select/src/organization-select.js +++ b/packages/organization-select/src/organization-select.js @@ -5,10 +5,10 @@ import {createInstance} from './i18n.js'; import {css, html} from 'lit'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import select2LangDe from "@dbp-toolkit/organization-select/src/i18n/de/select2"; -import select2LangEn from "@dbp-toolkit/organization-select/src/i18n/en/select2"; -import JSONLD from "@dbp-toolkit/common/jsonld"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import select2LangDe from '@dbp-toolkit/organization-select/src/i18n/de/select2'; +import select2LangEn from '@dbp-toolkit/organization-select/src/i18n/en/select2'; +import JSONLD from '@dbp-toolkit/common/jsonld'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; select2(window, $); @@ -34,10 +34,10 @@ export class OrganizationSelect extends AdapterLitElement { return { ...super.properties, lang: {type: String}, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, value: {type: String, reflect: true}, context: {type: String}, - auth: { type: Object }, + auth: {type: Object}, }; } @@ -46,7 +46,7 @@ export class OrganizationSelect extends AdapterLitElement { } select2IsInitialized(elm) { - return elm !== null && elm.hasClass("select2-hidden-accessible"); + return elm !== null && elm.hasClass('select2-hidden-accessible'); } connectedCallback() { @@ -83,7 +83,7 @@ export class OrganizationSelect extends AdapterLitElement { _clearSelect2() { const $select = this.$('#' + this.selectId); - console.assert($select.length, "select2 missing"); + console.assert($select.length, 'select2 missing'); // we need to destroy Select2 and remove the event listeners before we can initialize it again if (this.select2IsInitialized($select)) { @@ -98,7 +98,7 @@ export class OrganizationSelect extends AdapterLitElement { await this.updateComplete; const $select = this.$('#' + this.selectId); - console.assert($select.length, "select2 missing"); + console.assert($select.length, 'select2 missing'); // Show an empty select until we load the organizations if (this._needsLoading()) { @@ -106,37 +106,39 @@ export class OrganizationSelect extends AdapterLitElement { $select.select2({ width: '100%', - language: this.lang === "de" ? select2LangDe() : select2LangEn(), + language: this.lang === 'de' ? select2LangDe() : select2LangEn(), placeholder: i18n.t('select-organization.loading'), data: [], - disabled: true + disabled: true, }); } - this.removeAttribute("data-organizations-loaded"); + this.removeAttribute('data-organizations-loaded'); await this.load_organizations(); - this.setAttribute("data-organizations-loaded", ""); + this.setAttribute('data-organizations-loaded', ''); this._clearSelect2(); const data = this.organizations.map((item) => { - return {'id': item.object["@id"], 'text': item.code + ' ' + item.name}; + return {id: item.object['@id'], text: item.code + ' ' + item.name}; }); data.sort((a, b) => { return a.text < b.text ? -1 : a.text > b.text ? 1 : 0; }); - $select.select2({ - width: '100%', - language: this.lang === "de" ? select2LangDe() : select2LangEn(), - placeholder: i18n.t('select-organization.placeholder'), - dropdownParent: this.$('#select-organization-dropdown'), - data: data, - disabled: false - }).on("select2:select", () => { - this.value = $select.select2('data')[0].id; - }); + $select + .select2({ + width: '100%', + language: this.lang === 'de' ? select2LangDe() : select2LangEn(), + placeholder: i18n.t('select-organization.placeholder'), + dropdownParent: this.$('#select-organization-dropdown'), + data: data, + disabled: false, + }) + .on('select2:select', () => { + this.value = $select.select2('data')[0].id; + }); // If none is selected, default to the first one if (!this.value.length && data.length) { @@ -149,14 +151,14 @@ export class OrganizationSelect extends AdapterLitElement { fireEvent() { const organization = this.organizations.find((item) => { - return item.object["@id"] === this.value; + return item.object['@id'] === this.value; }); const $this = $(this); if (organization === undefined) { - $this.attr("data-object", null); - $this.data("object", null); + $this.attr('data-object', null); + $this.data('object', null); return; } @@ -166,42 +168,46 @@ export class OrganizationSelect extends AdapterLitElement { bubbles: true, composed: true, detail: { - 'value': organization.value, - 'object': organization.object, - } + value: organization.value, + object: organization.object, + }, }); this.dispatchEvent(event); } setDataObject(organization) { const $this = $(this); - $this.attr("data-object", JSON.stringify(organization.object)); - $this.data("object", organization.object); + $this.attr('data-object', JSON.stringify(organization.object)); + $this.data('object', organization.object); } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); this.updateSelect2(); break; - case "value": { + case 'value': { this.updateSelect2(); this.fireEvent(); break; } - case "context": { + case 'context': { delete this.cache[this.lang]; this.updateSelect2(); break; } - case "entryPointUrl": - JSONLD.getInstance(this.entryPointUrl).then((jsonld) => { - this.jsonld = jsonld; - }, {}, this.lang); + case 'entryPointUrl': + JSONLD.getInstance(this.entryPointUrl).then( + (jsonld) => { + this.jsonld = jsonld; + }, + {}, + this.lang + ); break; - case "auth": + case 'auth': this.initAuthPersonOnce().then(); break; default: @@ -212,7 +218,7 @@ export class OrganizationSelect extends AdapterLitElement { } async initAuthPersonOnce() { - if (!this.auth.person || this.hasAttribute("data-auth-person-init-finished")) { + if (!this.auth.person || this.hasAttribute('data-auth-person-init-finished')) { return; } @@ -220,7 +226,7 @@ export class OrganizationSelect extends AdapterLitElement { await this.updateSelect2(); // this attribute is used in end2end tests - this.setAttribute("data-auth-person-init-finished", ""); + this.setAttribute('data-auth-person-init-finished', ''); } /** @@ -233,21 +239,24 @@ export class OrganizationSelect extends AdapterLitElement { return []; } - let orgUrl = this.entryPointUrl + '/base/people/' + + let orgUrl = + this.entryPointUrl + + '/base/people/' + encodeURIComponent(this.auth['person-id']) + '/organizations' + - '?context=' + encodeURIComponent(this.context) + - '&lang=' + encodeURIComponent(this.lang); + '?context=' + + encodeURIComponent(this.context) + + '&lang=' + + encodeURIComponent(this.lang); let response = await fetch(orgUrl, { headers: { 'Content-Type': 'application/ld+json', - 'Authorization': 'Bearer ' + this.auth.token, + Authorization: 'Bearer ' + this.auth.token, }, }); - if (!response.ok) - throw new Error(response.statusText); + if (!response.ok) throw new Error(response.statusText); let data = await response.json(); @@ -283,16 +292,19 @@ export class OrganizationSelect extends AdapterLitElement { render() { const select2CSS = commonUtils.getAssetURL(select2CSSPath); return html` - <link rel="stylesheet" href="${select2CSS}"> - - <div class="select"> - <div class="select2-control control"> - <!-- https://select2.org--> - <select id="${this.selectId}" name="select-organization" class="select" style="visibility: hidden;"></select> + <link rel="stylesheet" href="${select2CSS}" /> + + <div class="select"> + <div class="select2-control control"> + <!-- https://select2.org--> + <select + id="${this.selectId}" + name="select-organization" + class="select" + style="visibility: hidden;"></select> + </div> + <div id="select-organization-dropdown"></div> </div> - <div id="select-organization-dropdown"></div> - </div> - `; } -} \ No newline at end of file +} diff --git a/packages/organization-select/test/unit.js b/packages/organization-select/test/unit.js index 962096878a072aae3e510e7ae6a188097e98d0b0..c6776fb53a1553ccafe03a7a6074ee17c825b9a6 100644 --- a/packages/organization-select/test/unit.js +++ b/packages/organization-select/test/unit.js @@ -4,37 +4,37 @@ import '../src/dbp-organization-select.js'; import '../src/demo.js'; suite('dbp-organization-select basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-organization-select'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-organization-select'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); suite('dbp-organization-select-demo basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-organization-select-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-organization-select-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/person-profile/.eslintrc.json b/packages/person-profile/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/person-profile/.eslintrc.json +++ b/packages/person-profile/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/person-profile/.prettierignore b/packages/person-profile/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/person-profile/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/person-profile/.prettierrc.json b/packages/person-profile/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/person-profile/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/person-profile/i18next-scanner.config.js b/packages/person-profile/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/person-profile/i18next-scanner.config.js +++ b/packages/person-profile/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/person-profile/karma.conf.js b/packages/person-profile/karma.conf.js index 6071887ad9307edce23bfa1bea46d2f9692f28d3..ca038af2286e2ad631f1c58d7216fbe4054e4199 100644 --- a/packages/person-profile/karma.conf.js +++ b/packages/person-profile/karma.conf.js @@ -1,2 +1 @@ module.exports = require('../../karma.common.conf.js'); - diff --git a/packages/person-profile/package.json b/packages/person-profile/package.json index d649ce396df6340d30c2e0c3d60e65227648e3ce..86917ca78fb34a0a942b84304aea0b6565d5945b 100644 --- a/packages/person-profile/package.json +++ b/packages/person-profile/package.json @@ -1,59 +1,63 @@ { - "name": "@dbp-toolkit/person-profile", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/person-profile", - "version": "0.2.3", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/person-profile" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@dbp-toolkit/person-select": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "jquery": "^3.4.1", - "lit": "^2.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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/person-profile", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/person-profile", + "version": "0.2.3", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/person-profile" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@dbp-toolkit/person-select": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "jquery": "^3.4.1", + "lit": "^2.0.0" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/person-profile/rollup.config.js b/packages/person-profile/rollup.config.js index ade77cbbf16192a50a5fc6748820ef11e6d43329..d7c339743f7c75dee7ad5de19cadc7ef7270dc08 100644 --- a/packages/person-profile/rollup.config.js +++ b/packages/person-profile/rollup.config.js @@ -1,51 +1,56 @@ - import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url" +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build != 'test') ? ['src/dbp-person-profile.js', 'src/dbp-person-profile-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-person-profile.js', 'src/dbp-person-profile-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), url({ limit: 0, - include: [ - await getPackagePath('select2', '**/*.css'), - ], + include: [await getPackagePath('select2', '**/*.css')], emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/person-profile/src/dbp-person-profile-demo.js b/packages/person-profile/src/dbp-person-profile-demo.js index cd6fbf9ffd8dc85a9b33ad64d82553d0277183d8..08e5a30bd29e3eaf9d2b6ff8b0d1ce9a53b3b196 100644 --- a/packages/person-profile/src/dbp-person-profile-demo.js +++ b/packages/person-profile/src/dbp-person-profile-demo.js @@ -23,40 +23,40 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { static get scopedElements() { return { - 'dbp-person-profile': PersonProfile, - 'dbp-auth-keycloak': AuthKeycloak, - 'dbp-login-button': LoginButton, - 'dbp-person-select': PersonSelect, + 'dbp-person-profile': PersonProfile, + 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-login-button': LoginButton, + 'dbp-person-select': PersonSelect, }; - } + } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - person: { type: String, attribute: false }, - selectedPerson: { type: String, attribute: false }, - noAuth: { type: Boolean, attribute: 'no-auth' }, - auth: { type: Object }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + person: {type: String, attribute: false}, + selectedPerson: {type: String, attribute: false}, + noAuth: {type: Boolean, attribute: 'no-auth'}, + auth: {type: Object}, }; } update(changedProperties) { - if (changedProperties.has("lang")) { + if (changedProperties.has('lang')) { this._i18n.changeLanguage(this.lang); } changedProperties.forEach((oldValue, propName) => { switch (propName) { case 'auth': - { - const person = this.auth.person; + { + const person = this.auth.person; - if (person) { - this.person = person.identifier; + if (person) { + this.person = person.identifier; + } } - } break; } }); @@ -68,12 +68,11 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { super.connectedCallback(); const that = this; - this.updateComplete.then(()=>{ + this.updateComplete.then(() => { const personSelect = that._(this.getScopedTagName('dbp-person-select')); personSelect.onchange = function () { - that.selectedPerson = $(this).data("object").identifier; + that.selectedPerson = $(this).data('object').identifier; }; - }); } @@ -83,20 +82,34 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { ${commonStyles.getThemeCSS()} ${commonStyles.getGeneralCSS()} - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } `; } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button>` : html` - <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" - url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" - client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> - <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> - </div> - `; + return this.noAuth + ? html` + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + ` + : html` + <div class="container"> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + url="https://auth-dev.tugraz.at/auth" + realm="tugraz-vpu" + client-id="auth-dev-mw-frontend-local" + try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + </div> + `; } render() { @@ -108,7 +121,11 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { <h1 class="title">Person-Profile-Demo</h1> </div> <div class="container"> - <dbp-person-profile subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" value="${this.person}"></dbp-person-profile> + <dbp-person-profile + subscribe="auth" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + value="${this.person}"></dbp-person-profile> </div> </section> <section class="section"> @@ -116,10 +133,17 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { <h1 class="title">Select-Profile-Demo</h1> </div> <div class="container"> - <dbp-person-select subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-person-select> + <dbp-person-select + subscribe="auth" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}"></dbp-person-select> </div> <div class="container"> - <dbp-person-profile subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" value="${this.selectedPerson}"></dbp-person-profile> + <dbp-person-profile + subscribe="auth" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + value="${this.selectedPerson}"></dbp-person-profile> </div> </section> `; diff --git a/packages/person-profile/src/i18n.js b/packages/person-profile/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/person-profile/src/i18n.js +++ b/packages/person-profile/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/person-profile/src/i18n/de/translation.json b/packages/person-profile/src/i18n/de/translation.json index 71b2d6ed32bbaeee2dbb3517abcb8141b6db7830..fd7f622fb8c1490912450bbff6cb2b8247ed7e3c 100644 --- a/packages/person-profile/src/i18n/de/translation.json +++ b/packages/person-profile/src/i18n/de/translation.json @@ -1,9 +1,9 @@ { - "person-profile": { - "profile-caption": "Profil von", - "given-name": "Vorname", - "family-name": "Nachname", - "email": "Email", - "none-selected": "Keine Person ausgewählt" - } + "person-profile": { + "profile-caption": "Profil von", + "given-name": "Vorname", + "family-name": "Nachname", + "email": "Email", + "none-selected": "Keine Person ausgewählt" + } } diff --git a/packages/person-profile/src/i18n/en/translation.json b/packages/person-profile/src/i18n/en/translation.json index 372e344fb57b60c699f92d6deb8e38d616c60ffc..80b4e4967ec13c2a0e1a189c3db841c8e5c9c72e 100644 --- a/packages/person-profile/src/i18n/en/translation.json +++ b/packages/person-profile/src/i18n/en/translation.json @@ -1,9 +1,9 @@ { - "person-profile": { - "profile-caption": "Profile for", - "given-name": "Given name", - "family-name": "Family name", - "email": "Email", - "none-selected": "No person selected" - } + "person-profile": { + "profile-caption": "Profile for", + "given-name": "Given name", + "family-name": "Family name", + "email": "Email", + "none-selected": "No person selected" + } } diff --git a/packages/person-profile/src/index.js b/packages/person-profile/src/index.js index 4e1db599f3cd96546d0ccc5b95d01fcfbd0f0231..763e67aa5f3621b42e30df8f1f89052a4adf5775 100644 --- a/packages/person-profile/src/index.js +++ b/packages/person-profile/src/index.js @@ -1,3 +1,3 @@ import {PersonProfile} from './person-profile.js'; -export {PersonProfile}; \ No newline at end of file +export {PersonProfile}; diff --git a/packages/person-profile/src/person-profile.js b/packages/person-profile/src/person-profile.js index c6b5c37676a59389c79879bcfb9ba8577c8553c0..125c1a4dbfda3c676496a1aba6d0d6f274be94d5 100644 --- a/packages/person-profile/src/person-profile.js +++ b/packages/person-profile/src/person-profile.js @@ -1,13 +1,10 @@ - import JSONLD from '@dbp-toolkit/common/jsonld'; import {css, html} from 'lit'; import {createInstance} from './i18n.js'; import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; import * as commonStyles from '@dbp-toolkit/common/styles'; - export class PersonProfile extends DBPLitElement { - constructor() { super(); this._i18n = createInstance(); @@ -21,27 +18,31 @@ export class PersonProfile extends DBPLitElement { static get properties() { return { - lang: { type: String }, - active: { type: Boolean, attribute: false }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - value: { type: String }, - person: { type: Object, attribute: false }, - auth: { type: Object }, + lang: {type: String}, + active: {type: Boolean, attribute: false}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + value: {type: String}, + person: {type: Object, attribute: false}, + auth: {type: Object}, }; } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); break; - case "entryPointUrl": { + case 'entryPointUrl': { const that = this; - JSONLD.getInstance(this.entryPointUrl).then(function (jsonld) { - that.jsonld = jsonld; - }, {}, that.lang); + JSONLD.getInstance(this.entryPointUrl).then( + function (jsonld) { + that.jsonld = jsonld; + }, + {}, + that.lang + ); break; } case 'value': @@ -52,10 +53,10 @@ export class PersonProfile extends DBPLitElement { fetch(apiUrl, { headers: { 'Content-Type': 'application/ld+json', - 'Authorization': 'Bearer ' + this.auth.token, + Authorization: 'Bearer ' + this.auth.token, }, }) - .then(response => response.json()) + .then((response) => response.json()) .then((person) => { this.person = person; }); @@ -81,24 +82,42 @@ export class PersonProfile extends DBPLitElement { return html` <style> - .profile { - padding: 1rem - } - .td-profile { - padding-right: 2rem - } + .profile { + padding: 1rem; + } + .td-profile { + padding-right: 2rem; + } </style> - ${this.person !== null ? html`<h3>${i18n.t('person-profile.profile-caption')} ${this.person.givenName} ${this.person.familyName}</h3> - <table class="profile"> - <thead></thead> - <tbody> - <tr><td class="td-profile">${i18n.t('person-profile.given-name')}</td><td>${this.person.givenName}</td></tr> - <tr><td class="td-profile">${i18n.t('person-profile.family-name')}</td><td>${this.person.familyName}</td></tr> - <tr><td class="td-profile">${i18n.t('person-profile.email')}</td><td>${this.person.email}</td></tr> - </tbody> - <tfoot></tfoot> - </table>` : i18n.t('person-profile.none-selected') } + ${this.person !== null + ? html` + <h3> + ${i18n.t('person-profile.profile-caption')} ${this.person.givenName} + ${this.person.familyName} + </h3> + <table class="profile"> + <thead></thead> + <tbody> + <tr> + <td class="td-profile">${i18n.t('person-profile.given-name')}</td> + <td>${this.person.givenName}</td> + </tr> + <tr> + <td class="td-profile"> + ${i18n.t('person-profile.family-name')} + </td> + <td>${this.person.familyName}</td> + </tr> + <tr> + <td class="td-profile">${i18n.t('person-profile.email')}</td> + <td>${this.person.email}</td> + </tr> + </tbody> + <tfoot></tfoot> + </table> + ` + : i18n.t('person-profile.none-selected')} `; } } diff --git a/packages/person-profile/test/unit.js b/packages/person-profile/test/unit.js index 09a3efbf6cda0ab35a6bc17bdef0228baee50e91..311541d175638c51dceadffcc10d2857dc9f754f 100644 --- a/packages/person-profile/test/unit.js +++ b/packages/person-profile/test/unit.js @@ -3,19 +3,19 @@ import {assert} from '@esm-bundle/chai'; import '../src/dbp-person-profile-demo.js'; suite('dbp-person-profile demo', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-person-profile-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-person-profile-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/person-select/.eslintrc.json b/packages/person-select/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/person-select/.eslintrc.json +++ b/packages/person-select/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/person-select/.prettierignore b/packages/person-select/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/person-select/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/person-select/.prettierrc.json b/packages/person-select/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/person-select/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/person-select/i18next-scanner.config.js b/packages/person-select/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/person-select/i18next-scanner.config.js +++ b/packages/person-select/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/person-select/package.json b/packages/person-select/package.json index 6e078f4b667886e9e45470b982af0024c1c0dc01..89bde452376b46bd9d64c8f8f3f88a1bbe33d80c 100644 --- a/packages/person-select/package.json +++ b/packages/person-select/package.json @@ -1,60 +1,64 @@ { - "name": "@dbp-toolkit/person-select", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/person-select", - "version": "0.2.3", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/person-select" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-replace": "^3.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "jquery": "^3.4.1", - "lit": "^2.0.0", - "select2": "^4.0.10" - }, - "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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/person-select", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/person-select", + "version": "0.2.3", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/person-select" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-replace": "^3.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "jquery": "^3.4.1", + "lit": "^2.0.0", + "select2": "^4.0.10" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/person-select/rollup.config.js b/packages/person-select/rollup.config.js index cbc4cd852c3cb7e19a6cec8e73b99e1566ea3ebc..c2c31bd722c7db7b637011c0de85da8cfd5ec883 100644 --- a/packages/person-select/rollup.config.js +++ b/packages/person-select/rollup.config.js @@ -2,49 +2,55 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url" +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default (async () => { return { - input: (build != 'test') ? ['src/dbp-person-select.js', 'src/dbp-person-select-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-person-select.js', 'src/dbp-person-select-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), url({ limit: 0, - include: [ - await getPackagePath('select2', '**/*.css'), - ], + include: [await getPackagePath('select2', '**/*.css')], emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/person-select/src/dbp-person-select-demo.js b/packages/person-select/src/dbp-person-select-demo.js index cf817cebb2d0e68c089da5d7711d0124c1c8dd22..18ab05f5bef03fd4638ddc66255178ca21ffc1bb 100644 --- a/packages/person-select/src/dbp-person-select-demo.js +++ b/packages/person-select/src/dbp-person-select-demo.js @@ -5,7 +5,7 @@ import {PersonSelect} from './person-select.js'; import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; export class PersonSelectDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { @@ -18,18 +18,18 @@ export class PersonSelectDemo extends ScopedElementsMixin(DBPLitElement) { static get scopedElements() { return { - 'dbp-auth-keycloak': AuthKeycloak, - 'dbp-login-button': LoginButton, - 'dbp-person-select': PersonSelect, + 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-login-button': LoginButton, + 'dbp-person-select': PersonSelect, }; } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - noAuth: { type: Boolean, attribute: 'no-auth' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + noAuth: {type: Boolean, attribute: 'no-auth'}, }; } @@ -39,28 +39,42 @@ export class PersonSelectDemo extends ScopedElementsMixin(DBPLitElement) { commonStyles.getThemeCSS(), commonStyles.getGeneralCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} - ` + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } + `, ]; } update(changedProperties) { - if (changedProperties.has("lang")) { + if (changedProperties.has('lang')) { this._i18n.changeLanguage(this.lang); } super.update(changedProperties); } getAuthComponentHtml() { - return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button>` : html` - <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html" - url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" - client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> - <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> - </div> - `; + return this.noAuth + ? html` + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + ` + : html` + <div class="container"> + <dbp-auth-keycloak + subscribe="requested-login-status" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + silent-check-sso-redirect-uri="/dist/silent-check-sso.html" + url="https://auth-dev.tugraz.at/auth" + realm="tugraz-vpu" + client-id="auth-dev-mw-frontend-local" + try-login></dbp-auth-keycloak> + <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> + </div> + `; } render() { @@ -75,21 +89,36 @@ export class PersonSelectDemo extends ScopedElementsMixin(DBPLitElement) { <div class="field"> <label class="label">Person 1</label> <div class="control"> - <dbp-person-select subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-person-select> + <dbp-person-select + subscribe="auth" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}"></dbp-person-select> </div> </div> <div class="field"> <label class="label">Person 2</label> <div class="control"> - <dbp-person-select subscribe="auth" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" show-reload-button reload-button-title="Click me"></dbp-person-select> + <dbp-person-select + subscribe="auth" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + show-reload-button + reload-button-title="Click me"></dbp-person-select> </div> </div> <div class="field"> <label class="label">Person 3 unsubscribed</label> <div class="control"> - <dbp-person-select lang="${this.lang}" entry-point-url="${this.entryPointUrl}" show-reload-button reload-button-title="Click me"></dbp-person-select> + <dbp-person-select + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + show-reload-button + reload-button-title="Click me"></dbp-person-select> </div> - <p>This component doesn't get any notification about user's login and will become active.</p> + <p> + This component doesn't get any notification about user's login and + will become active. + </p> </div> </form> </div> diff --git a/packages/person-select/src/i18n.js b/packages/person-select/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/person-select/src/i18n.js +++ b/packages/person-select/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/person-select/src/i18n/de/select2.js b/packages/person-select/src/i18n/de/select2.js index bef156f0f506c91c494fa5fc1c7a7b49a8a97d9c..14d5c25e6b1a6b686274710751da7bbe72aa6c0b 100644 --- a/packages/person-select/src/i18n/de/select2.js +++ b/packages/person-select/src/i18n/de/select2.js @@ -15,7 +15,11 @@ export default function () { inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; - return 'Bitte ' + remainingChars + ' Zeichen mehr eingeben, es kann nach mehreren Teilen von Namen gesucht werden'; + return ( + 'Bitte ' + + remainingChars + + ' Zeichen mehr eingeben, es kann nach mehreren Teilen von Namen gesucht werden' + ); }, loadingMore: function () { return 'Lade mehr Ergebnisse…'; @@ -41,6 +45,6 @@ export default function () { }, removeAllItems: function () { return 'Entferne alle Gegenstände'; - } + }, }; } diff --git a/packages/person-select/src/i18n/de/translation.json b/packages/person-select/src/i18n/de/translation.json index 4528f9010fd698f94f26739d01e2d1eb9a6d6b41..45fbe6f07b1954ea5c141e367369e54cdce1091a 100644 --- a/packages/person-select/src/i18n/de/translation.json +++ b/packages/person-select/src/i18n/de/translation.json @@ -1,6 +1,6 @@ { - "person-select": { - "placeholder": "Bitte wählen Sie eine Person aus", - "login-required": "Anmeldung erforderlich" - } + "person-select": { + "placeholder": "Bitte wählen Sie eine Person aus", + "login-required": "Anmeldung erforderlich" + } } diff --git a/packages/person-select/src/i18n/en/select2.js b/packages/person-select/src/i18n/en/select2.js index d172d72ef06e17651dda4d2f6d73ef49e50cf845..c6ff8f0a2febdf95de10ae02155e2337ca4e13c5 100644 --- a/packages/person-select/src/i18n/en/select2.js +++ b/packages/person-select/src/i18n/en/select2.js @@ -21,7 +21,10 @@ export default function () { inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; - var message = 'Please enter ' + remainingChars + ' or more characters, you can also search for multiple parts of names'; + var message = + 'Please enter ' + + remainingChars + + ' or more characters, you can also search for multiple parts of names'; return message; }, @@ -45,6 +48,6 @@ export default function () { }, removeAllItems: function () { return 'Remove all items'; - } + }, }; } diff --git a/packages/person-select/src/i18n/en/translation.json b/packages/person-select/src/i18n/en/translation.json index 9bcb748c767c334de390e3c032250dd01f91c088..29d43e0411ec744e45aa97199228eb7664634b8a 100644 --- a/packages/person-select/src/i18n/en/translation.json +++ b/packages/person-select/src/i18n/en/translation.json @@ -1,6 +1,6 @@ { - "person-select": { - "placeholder": "Please select a person", - "login-required": "Login required" - } + "person-select": { + "placeholder": "Please select a person", + "login-required": "Login required" + } } diff --git a/packages/person-select/src/index.js b/packages/person-select/src/index.js index 776fa475b7f2f3ffc747cbe24194838f65fca3b2..e32dc2ddd4d62a6186f5aaaa015c0d1d09536ddc 100644 --- a/packages/person-select/src/index.js +++ b/packages/person-select/src/index.js @@ -1,3 +1,3 @@ import {PersonSelect} from './person-select.js'; -export {PersonSelect}; \ No newline at end of file +export {PersonSelect}; diff --git a/packages/person-select/src/person-select.js b/packages/person-select/src/person-select.js index 6f30a8cb73b1f4703cc88314db41d2d9196badc0..533f8f13f1c4e37b4452b8d69aaf60ece005ee28 100644 --- a/packages/person-select/src/person-select.js +++ b/packages/person-select/src/person-select.js @@ -11,21 +11,19 @@ import {Icon} from '@dbp-toolkit/common'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import select2CSSPath from 'select2/dist/css/select2.min.css'; -import * as errorUtils from "@dbp-toolkit/common/error"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; - +import * as errorUtils from '@dbp-toolkit/common/error'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; const personContext = { - "@id": "@id", - "givenName": "http://schema.org/givenName", - "familyName": "http://schema.org/familyName", - "email": "http://schema.org/email" + '@id': '@id', + givenName: 'http://schema.org/givenName', + familyName: 'http://schema.org/familyName', + email: 'http://schema.org/email', }; select2(window, $); export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { - constructor() { super(); Object.assign(PersonSelect.prototype, errorUtils.errorMixin); @@ -52,7 +50,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { static get scopedElements() { return { - 'dbp-icon': Icon, + 'dbp-icon': Icon, }; } @@ -63,26 +61,26 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, - active: { type: Boolean, attribute: false }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - value: { type: String }, - object: { type: Object, attribute: false }, - showReloadButton: { type: Boolean, attribute: 'show-reload-button' }, - reloadButtonTitle: { type: String, attribute: 'reload-button-title' }, - showDetails: { type: Boolean, attribute: 'show-details' }, - auth: { type: Object }, + lang: {type: String}, + active: {type: Boolean, attribute: false}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + value: {type: String}, + object: {type: Object, attribute: false}, + showReloadButton: {type: Boolean, attribute: 'show-reload-button'}, + reloadButtonTitle: {type: String, attribute: 'reload-button-title'}, + showDetails: {type: Boolean, attribute: 'show-details'}, + auth: {type: Object}, }; } clear() { this.object = null; - $(this).attr("data-object", ""); - $(this).data("object", null); - this.value = ""; + $(this).attr('data-object', ''); + $(this).data('object', null); + this.value = ''; // Reset value attribute to really make sure it is empty and will trigger a change event // when it is set again with the previous value - $(this).attr("value", ""); + $(this).attr('value', ''); this.$select.val(null).trigger('change').trigger('select2:unselect'); } @@ -90,7 +88,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { super.connectedCallback(); document.addEventListener('click', this._onDocumentClicked); - this.updateComplete.then(()=>{ + this.updateComplete.then(() => { this.$select = this.$('#' + this.selectId); // try an init when user-interface is loaded this.initJSONLD(); @@ -115,14 +113,24 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { initJSONLD(ignorePreset = false) { const that = this; - JSONLD.getInstance(this.entryPointUrl).then(function (jsonld) { - that.jsonld = jsonld; - that.active = that.authenticated(); + JSONLD.getInstance(this.entryPointUrl).then( + function (jsonld) { + that.jsonld = jsonld; + that.active = that.authenticated(); - // we need to poll because maybe the user interface isn't loaded yet - // Note: we need to call initSelect2() in a different function so we can access "this" inside initSelect2() - commonUtils.pollFunc(() => { return that.initSelect2(ignorePreset); }, 10000, 100); - }, {}, this.lang); + // we need to poll because maybe the user interface isn't loaded yet + // Note: we need to call initSelect2() in a different function so we can access "this" inside initSelect2() + commonUtils.pollFunc( + () => { + return that.initSelect2(ignorePreset); + }, + 10000, + 100 + ); + }, + {}, + this.lang + ); } /** @@ -140,7 +148,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { } // find the correct api url for a person - const apiUrl = this.jsonld.getApiUrlForIdentifier("http://schema.org/Person"); + const apiUrl = this.jsonld.getApiUrlForIdentifier('http://schema.org/Person'); // const apiUrl = this.jsonld.getApiUrlForEntityName("Event"); if (this.$select === null) { @@ -154,71 +162,83 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { this.$select.off('select2:closing'); } - this.$select.select2({ - width: '100%', - language: this.lang === "de" ? select2LangDe() : select2LangEn(), - minimumInputLength: 2, - placeholder: this.authenticated() ? i18n.t('person-select.placeholder') : i18n.t('person-select.login-required'), - dropdownParent: this.$('#person-select-dropdown'), - ajax: { - delay: 500, - url: apiUrl, - contentType: "application/ld+json", - beforeSend: function (jqXHR) { - jqXHR.setRequestHeader('Authorization', 'Bearer ' + that.auth.token); - that.isSearching = true; - }, - data: function (params) { - return { - search: params.term.trim(), - }; - }, - processResults: function (data) { - that.$('#person-select-dropdown').addClass('select2-bug'); - - that.lastResult = data; - let transformed = that.jsonld.transformMembers(data, personContext); - const results = []; - transformed.forEach((person) => { - results.push({id: person["@id"], text: that.generateOptionText(person)}); - }); - - return { - results: results - }; + this.$select + .select2({ + width: '100%', + language: this.lang === 'de' ? select2LangDe() : select2LangEn(), + minimumInputLength: 2, + placeholder: this.authenticated() + ? i18n.t('person-select.placeholder') + : i18n.t('person-select.login-required'), + dropdownParent: this.$('#person-select-dropdown'), + ajax: { + delay: 500, + url: apiUrl, + contentType: 'application/ld+json', + beforeSend: function (jqXHR) { + jqXHR.setRequestHeader('Authorization', 'Bearer ' + that.auth.token); + that.isSearching = true; + }, + data: function (params) { + return { + search: params.term.trim(), + }; + }, + processResults: function (data) { + that.$('#person-select-dropdown').addClass('select2-bug'); + + that.lastResult = data; + let transformed = that.jsonld.transformMembers(data, personContext); + const results = []; + transformed.forEach((person) => { + results.push({ + id: person['@id'], + text: that.generateOptionText(person), + }); + }); + + return { + results: results, + }; + }, + error: (jqXHR, textStatus, errorThrown) => { + this.handleXhrError(jqXHR, textStatus, errorThrown); + }, + complete: (jqXHR, textStatus) => { + that.isSearching = false; + }, }, - error: (jqXHR, textStatus, errorThrown) => { this.handleXhrError(jqXHR, textStatus, errorThrown); }, - complete: (jqXHR, textStatus) => { - that.isSearching = false; + }) + .on('select2:select', function (e) { + that.$('#person-select-dropdown').removeClass('select2-bug'); + + // set custom element attributes + const identifier = e.params.data.id; + that.object = findObjectInApiResults(identifier, that.lastResult); + + $this.attr('data-object', JSON.stringify(that.object)); + $this.data('object', that.object); + + if ($this.attr('value') !== identifier) { + that.ignoreValueUpdate = true; + $this.attr('value', identifier); + + // fire a change event + that.dispatchEvent( + new CustomEvent('change', { + detail: { + value: identifier, + }, + bubbles: true, + }) + ); } - } - }).on("select2:select", function (e) { - that.$('#person-select-dropdown').removeClass('select2-bug'); - - // set custom element attributes - const identifier = e.params.data.id; - that.object = findObjectInApiResults(identifier, that.lastResult); - - $this.attr("data-object", JSON.stringify(that.object)); - $this.data("object", that.object); - - if ($this.attr("value") !== identifier) { - that.ignoreValueUpdate = true; - $this.attr("value", identifier); - - // fire a change event - that.dispatchEvent(new CustomEvent('change', { - detail: { - value: identifier, - }, - bubbles: true - })); - } - }).on("select2:closing", (e) => { - if (that.isSearching) { - e.preventDefault(); - } - }); + }) + .on('select2:closing', (e) => { + if (that.isSearching) { + e.preventDefault(); + } + }); // TODO: doesn't work here // this.$('.select2-selection__arrow').click(() => { @@ -232,48 +252,59 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { fetch(apiUrl, { headers: { 'Content-Type': 'application/ld+json', - 'Authorization': 'Bearer ' + this.auth.token, + Authorization: 'Bearer ' + this.auth.token, }, }) - .then(result => { - if (!result.ok) throw result; - return result.json(); - }) - .then((person) => { - that.object = person; - const transformed = that.jsonld.compactMember(that.jsonld.expandMember(person), personContext); - const identifier = transformed["@id"]; - - const option = new Option(that.generateOptionText(transformed), identifier, true, true); - $this.attr("data-object", JSON.stringify(person)); - $this.data("object", person); - that.$select.append(option).trigger('change'); - - // fire a change event - that.dispatchEvent(new CustomEvent('change', { - detail: { - value: identifier, - }, - bubbles: true - })); - }).catch((e) => { - console.log(e); - that.clear(); - }); + .then((result) => { + if (!result.ok) throw result; + return result.json(); + }) + .then((person) => { + that.object = person; + const transformed = that.jsonld.compactMember( + that.jsonld.expandMember(person), + personContext + ); + const identifier = transformed['@id']; + + const option = new Option( + that.generateOptionText(transformed), + identifier, + true, + true + ); + $this.attr('data-object', JSON.stringify(person)); + $this.data('object', person); + that.$select.append(option).trigger('change'); + + // fire a change event + that.dispatchEvent( + new CustomEvent('change', { + detail: { + value: identifier, + }, + bubbles: true, + }) + ); + }) + .catch((e) => { + console.log(e); + that.clear(); + }); } return true; } generateOptionText(person) { - let text = person["givenName"] ?? ''; - if (person["familyName"]) { - text += ` ${person["familyName"]}`; + let text = person['givenName'] ?? ''; + if (person['familyName']) { + text += ` ${person['familyName']}`; } // add birth date to name if present - if (this.showDetails && (person["email"] !== undefined) && (person["email"] !== null)) { - text += ` (${person["email"]})`; + if (this.showDetails && person['email'] !== undefined && person['email'] !== null) { + text += ` (${person['email']})`; } return text; @@ -282,7 +313,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); if (this.select2IsInitialized()) { @@ -290,18 +321,18 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { this.initSelect2(true); } break; - case "value": + case 'value': if (!this.ignoreValueUpdate && this.select2IsInitialized()) { this.initSelect2(); } this.ignoreValueUpdate = false; break; - case "entryPointUrl": + case 'entryPointUrl': // we don't need to preset the selector if the entry point url changes this.initJSONLD(true); break; - case "auth": + case 'auth': this.active = this.authenticated(); break; } @@ -311,7 +342,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { } select2IsInitialized() { - return this.$select !== null && this.$select.hasClass("select2-hidden-accessible"); + return this.$select !== null && this.$select.hasClass('select2-hidden-accessible'); } reloadClick() { @@ -320,12 +351,14 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { } // fire a change event - this.dispatchEvent(new CustomEvent('change', { - detail: { - value: this.value, - }, - bubbles: true - })); + this.dispatchEvent( + new CustomEvent('change', { + detail: { + value: this.value, + }, + bubbles: true, + }) + ); } authenticated() { @@ -340,30 +373,30 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { commonStyles.getFormAddonsCSS(), commonStyles.getSelect2CSS(), css` - .select2-control.control { - width: 100%; - } + .select2-control.control { + width: 100%; + } - .field .button.control { - display: flex; - align-items: center; - justify-content: center; - border: var(--dbp-border); - border-color: var(--dbp-text-muted); - -moz-border-radius-topright: var(--dbp-border-radius); - -moz-border-radius-bottomright: var(--dbp-border-radius); - line-height: 100%; - } + .field .button.control { + display: flex; + align-items: center; + justify-content: center; + border: var(--dbp-border); + border-color: var(--dbp-text-muted); + -moz-border-radius-topright: var(--dbp-border-radius); + -moz-border-radius-bottomright: var(--dbp-border-radius); + line-height: 100%; + } - .field .button.control dbp-icon { - top: 0; - } + .field .button.control dbp-icon { + top: 0; + } - /* https://github.com/select2/select2/issues/5457 */ - .select2-bug .loading-results { - display: none !important; - } - ` + /* https://github.com/select2/select2/issues/5457 */ + .select2-bug .loading-results { + display: none !important; + } + `, ]; } @@ -371,7 +404,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { const i18n = this._i18n; const select2CSS = commonUtils.getAssetURL(select2CSSPath); return html` - <link rel="stylesheet" href="${select2CSS}"> + <link rel="stylesheet" href="${select2CSS}" /> <style> #${this.selectId} { width: 100%; @@ -382,17 +415,27 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { <div class="field has-addons"> <div class="select2-control control"> <!-- https://select2.org--> - <select id="${this.selectId}" name="person" class="select" - ?disabled=${!this.active}> - ${!this.authenticated() ? html`<option value="" disabled selected>${ i18n.t('person-select.login-required')}</option>` : ''} + <select + id="${this.selectId}" + name="person" + class="select" + ?disabled=${!this.active}> + ${!this.authenticated() + ? html` + <option value="" disabled selected> + ${i18n.t('person-select.login-required')} + </option> + ` + : ''} </select> </div> - <a class="control button" - id="reload-button" - ?disabled=${this.object === null} - @click="${this.reloadClick}" - style="display: ${this.showReloadButton ? "flex" : "none"}" - title="${this.reloadButtonTitle}"> + <a + class="control button" + id="reload-button" + ?disabled=${this.object === null} + @click="${this.reloadClick}" + style="display: ${this.showReloadButton ? 'flex' : 'none'}" + title="${this.reloadButtonTitle}"> <dbp-icon name="reload"></dbp-icon> </a> </div> @@ -400,4 +443,4 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { </div> `; } -} \ No newline at end of file +} diff --git a/packages/person-select/src/utils.js b/packages/person-select/src/utils.js index 97d072d913ec7441ed76a704dc8658458ca0773b..167646f3b0ca2e9b656a3381e35e0b393d023e26 100644 --- a/packages/person-select/src/utils.js +++ b/packages/person-select/src/utils.js @@ -1,4 +1,3 @@ - /** * Finds an object in a JSON result by identifier * @@ -6,14 +5,14 @@ * @param results * @param identifierAttribute */ -export const findObjectInApiResults = (identifier, results, identifierAttribute = "@id") => { - const members = results["hydra:member"]; +export const findObjectInApiResults = (identifier, results, identifierAttribute = '@id') => { + const members = results['hydra:member']; if (members === undefined) { return; } - for (const object of members){ + for (const object of members) { if (object[identifierAttribute] === identifier) { return object; } diff --git a/packages/person-select/test/unit.js b/packages/person-select/test/unit.js index 8468b3e85ba28f4576dca99291e3f9953913b19d..2138852232bd7bcaaec53c1e8b3ad2fecc7e46d7 100644 --- a/packages/person-select/test/unit.js +++ b/packages/person-select/test/unit.js @@ -4,37 +4,37 @@ import '../src/dbp-person-select.js'; import '../src/demo.js'; suite('dbp-person-select basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-person-select'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-person-select'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); suite('dbp-person-select-demo basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-person-select-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-person-select-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/provider/.eslintrc.json b/packages/provider/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/provider/.eslintrc.json +++ b/packages/provider/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/provider/.prettierignore b/packages/provider/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/provider/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/provider/.prettierrc.json b/packages/provider/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/provider/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/provider/i18next-scanner.config.js b/packages/provider/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/provider/i18next-scanner.config.js +++ b/packages/provider/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/provider/package.json b/packages/provider/package.json index 47f2b0b35506182d56532e565473eefb5e3bf665..14e1d933922e080c251272fa449c547e7202fff2 100644 --- a/packages/provider/package.json +++ b/packages/provider/package.json @@ -1,58 +1,62 @@ { - "name": "@dbp-toolkit/provider", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/provider", - "version": "0.2.5", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/provider" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "glob": "^7.1.6", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.19.0", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.5", - "@dbp-toolkit/common": "^0.2.12", - "@open-wc/scoped-elements": "^2.0.0", - "lit": "^2.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": "rollup -c --watch", - "watch-local": "yarn run watch", - "watch-dev": "rollup -c --watch --environment BUILD:development", - "test": "rollup -c --environment BUILD:test && karma start --singleRun", - "lint": "eslint ." - } + "name": "@dbp-toolkit/provider", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/provider", + "version": "0.2.5", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/provider" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "glob": "^7.1.6", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.19.0", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.5", + "@dbp-toolkit/common": "^0.2.12", + "@open-wc/scoped-elements": "^2.0.0", + "lit": "^2.0.0" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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": "rollup -c --watch", + "watch-local": "yarn run watch", + "watch-dev": "rollup -c --watch --environment BUILD:development", + "test": "rollup -c --environment BUILD:test && karma start --singleRun", + "lint": "eslint ." + } } diff --git a/packages/provider/rollup.config.js b/packages/provider/rollup.config.js index 3a1aee65883355d6b692b862536fb077c13d9780..1c3ff27e9f92e422890efee92c3391af13afd352 100644 --- a/packages/provider/rollup.config.js +++ b/packages/provider/rollup.config.js @@ -2,17 +2,17 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url"; +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; -import emitEJS from 'rollup-plugin-emit-ejs' +import emitEJS from 'rollup-plugin-emit-ejs'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); function getBuildInfo() { const child_process = require('child_process'); @@ -24,7 +24,7 @@ function getBuildInfo() { let parsed = url.parse(remote); // convert git urls if (parsed.protocol === null) { - parsed = url.parse('git://' + remote.replace(":", "/")); + parsed = url.parse('git://' + remote.replace(':', '/')); parsed.protocol = 'https:'; } let newPath = parsed.path.slice(0, parsed.path.lastIndexOf('.')); @@ -34,23 +34,26 @@ function getBuildInfo() { info: commit, url: newUrl, time: new Date().toISOString(), - env: build - } + env: build, + }; } export default (async () => { return { - input: (build != 'test') ? ['src/dbp-provider.js', 'src/dbp-adapter.js','src/dbp-provider-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-provider.js', 'src/dbp-adapter.js', 'src/dbp-provider-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), emitEJS({ src: 'assets', @@ -64,29 +67,32 @@ export default (async () => { }, name: pkg.name, environment: build, - buildInfo: getBuildInfo() - } + buildInfo: getBuildInfo(), + }, }), resolve(), commonjs(), url({ limit: 0, - include: [ - await getPackagePath('select2', '**/*.css'), - ], + include: [await getPackagePath('select2', '**/*.css')], emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, - {src: 'assets/favicon.ico', dest:'dist'}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, + {src: 'assets/favicon.ico', dest: 'dist'}, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/provider/src/adapter-lit-element.js b/packages/provider/src/adapter-lit-element.js index 573b152b06a44e2f74975c0728cdcad348c36b4d..f84ecd358fbd22a5a0d58b2d08db42c12a2152fe 100644 --- a/packages/provider/src/adapter-lit-element.js +++ b/packages/provider/src/adapter-lit-element.js @@ -1 +1 @@ -export {AdapterLitElement} from "@dbp-toolkit/common"; +export {AdapterLitElement} from '@dbp-toolkit/common'; diff --git a/packages/provider/src/adapter.js b/packages/provider/src/adapter.js index f0842fa928db507d0a4f1b82dc04d2319f11031a..8a67ec17b8228eccf4977039ce882487d7baa7f0 100644 --- a/packages/provider/src/adapter.js +++ b/packages/provider/src/adapter.js @@ -23,95 +23,126 @@ export class Adapter extends HTMLElement { } connectedCallback() { - this.connected = true; const that = this; - // get all *not observed* attributes if (this.hasAttributes()) { const attrs = this.attributes; - for(let i = attrs.length - 1; i >= 0; i--) { + for (let i = attrs.length - 1; i >= 0; i--) { if (['id', 'class', 'style', 'data-tag-name'].includes(attrs[i].name)) { continue; } this.setPropertiesToChildNodes(); - this.attributeChangedCallback(attrs[i].name, this.getPropertyByAttributeName(attrs[i].name), attrs[i].value); - - console.debug('AdapterProvider (' + that.tagName + ') found attribute "' + attrs[i].name + '" = "' + attrs[i].value + '"'); + this.attributeChangedCallback( + attrs[i].name, + this.getPropertyByAttributeName(attrs[i].name), + attrs[i].value + ); + + console.debug( + 'AdapterProvider (' + + that.tagName + + ') found attribute "' + + attrs[i].name + + '" = "' + + attrs[i].value + + '"' + ); } } } disconnectedCallback() { const attrs = this.subscribe.split(','); - attrs.forEach(element => this.unSubscribeProviderFor(element)); + attrs.forEach((element) => this.unSubscribeProviderFor(element)); } subscribeProviderFor(element) { - console.debug('AdapterProvider(' + this.tagName + ') subscribeProviderFor( ' + element + ' )'); + console.debug( + 'AdapterProvider(' + this.tagName + ') subscribeProviderFor( ' + element + ' )' + ); const pair = element.trim().split(':'); const local = pair[0]; const global = pair[1] || local; const that = this; - const event = new CustomEvent('dbp-subscribe', - { - bubbles: true, - composed: true, - detail: { - name: global, - callback: (value) => { - console.debug('AdapterProvider(' + that.tagName + ') sub/Callback ' + global + ' -> ' + local + ' = ' + value); - that.setPropertiesToChildNodes(local, value); - - // If value is an object set it directly as property - if (typeof value === 'object' && value !== null) { - // console.debug("value is object", value); - that.setPropertyByAttributeName(local, value); - } else { - // console.debug("local, that.getPropertyByAttributeName(local), value", local, that.getPropertyByAttributeName(local), value); - that.attributeChangedCallback(local, that.getPropertyByAttributeName(local), value); - - // check if an attribute also exists in the tag - if (that.getAttribute(local) !== null) { - // we don't support attributes and provider values at the same time - console.warn('Provider callback: "' + local + '" is also an attribute in tag "' + that.tagName + '", this is not supported!'); - - // update attribute if reflectAttribute is enabled - if (that.reflectAttribute) { - that.setAttribute(local, value); - } + const event = new CustomEvent('dbp-subscribe', { + bubbles: true, + composed: true, + detail: { + name: global, + callback: (value) => { + console.debug( + 'AdapterProvider(' + + that.tagName + + ') sub/Callback ' + + global + + ' -> ' + + local + + ' = ' + + value + ); + that.setPropertiesToChildNodes(local, value); + + // If value is an object set it directly as property + if (typeof value === 'object' && value !== null) { + // console.debug("value is object", value); + that.setPropertyByAttributeName(local, value); + } else { + // console.debug("local, that.getPropertyByAttributeName(local), value", local, that.getPropertyByAttributeName(local), value); + that.attributeChangedCallback( + local, + that.getPropertyByAttributeName(local), + value + ); + + // check if an attribute also exists in the tag + if (that.getAttribute(local) !== null) { + // we don't support attributes and provider values at the same time + console.warn( + 'Provider callback: "' + + local + + '" is also an attribute in tag "' + + that.tagName + + '", this is not supported!' + ); + + // update attribute if reflectAttribute is enabled + if (that.reflectAttribute) { + that.setAttribute(local, value); } } - }, - sender: this, - } - }); + } + }, + sender: this, + }, + }); this.dispatchEvent(event); } unSubscribeProviderFor(element) { - console.debug('AdapterProvider(' + this.tagName + ') unSubscribeProviderFor( ' + element + ' )'); + console.debug( + 'AdapterProvider(' + this.tagName + ') unSubscribeProviderFor( ' + element + ' )' + ); const pair = element.trim().split(':'); const global = pair[1] || pair[0]; - const event = new CustomEvent('dbp-unsubscribe', - { - bubbles: true, - composed: true, - detail: { - name: global, - sender: this, - } - }); + const event = new CustomEvent('dbp-unsubscribe', { + bubbles: true, + composed: true, + detail: { + name: global, + sender: this, + }, + }); this.dispatchEvent(event); } static get properties() { return { - subscribe: { type: String }, - unsubscribe: { type: String }, + subscribe: {type: String}, + unsubscribe: {type: String}, }; } @@ -133,14 +164,22 @@ export class Adapter extends HTMLElement { } attributeChangedCallback(name, oldValue, newValue) { - switch(name) { + switch (name) { case 'subscribe': - console.debug('AdapterProvider() attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')'); + console.debug( + 'AdapterProvider() attributeChangesCallback( ' + + name + + ', ' + + oldValue + + ', ' + + newValue + + ')' + ); if (this.subscribe && this.subscribe.length > 0) { if (this.connected) { const attrs = this.subscribe.split(','); - attrs.forEach(element => this.unSubscribeProviderFor(element)); + attrs.forEach((element) => this.unSubscribeProviderFor(element)); } else { this.deferUnSubscribe = this.subscribe.length > 0; this.unsubscribe = this.subscribe; @@ -151,7 +190,7 @@ export class Adapter extends HTMLElement { this.subscribe = newValue; if (this.connected) { const attrs = newValue.split(','); - attrs.forEach(element => this.subscribeProviderFor(element)); + attrs.forEach((element) => this.subscribeProviderFor(element)); } else { this.deferSubscribe = newValue && newValue.length > 0; } @@ -160,7 +199,6 @@ export class Adapter extends HTMLElement { default: break; } - } /** @@ -171,19 +209,17 @@ export class Adapter extends HTMLElement { * @returns {boolean} */ sendSetPropertyEvent(name, value) { - const event = new CustomEvent("set-property", { + const event = new CustomEvent('set-property', { bubbles: true, composed: true, - detail: {'name': name, 'value': value} + detail: {name: name, value: value}, }); return this.dispatchEvent(event); } - setPropertiesToChildNodes(local, value) - { + setPropertiesToChildNodes(local, value) { let children = this.children; - Array.from(children).forEach(child => child.setAttribute(local, value)); + Array.from(children).forEach((child) => child.setAttribute(local, value)); } - } diff --git a/packages/provider/src/dbp-provider-demo.js b/packages/provider/src/dbp-provider-demo.js index 822a529998dfe8a3715f2cd07a44fca64bdf7be7..becd642c56488cada2f6b3931d69d343b2eae17a 100644 --- a/packages/provider/src/dbp-provider-demo.js +++ b/packages/provider/src/dbp-provider-demo.js @@ -7,11 +7,9 @@ import * as commonStyles from '@dbp-toolkit/common/styles'; import {Provider} from '@dbp-toolkit/provider'; import {Adapter} from '@dbp-toolkit/provider'; import {LanguageSelect} from '@dbp-toolkit/language-select'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; - +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { - constructor() { super(); this._i18n = createInstance(); @@ -32,13 +30,23 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, + lang: {type: String}, }; } attributeChangedCallback(name, oldValue, newValue) { - console.debug('ProviderDemo (' + this.id + ') attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')'); - switch(name) { + console.debug( + 'ProviderDemo (' + + this.id + + ') attributeChangesCallback( ' + + name + + ', ' + + oldValue + + ', ' + + newValue + + ')' + ); + switch (name) { case 'lang': this.lang = newValue; this._i18n.changeLanguage(this.lang); @@ -55,9 +63,14 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { commonStyles.getThemeCSS(), commonStyles.getGeneralCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em; padding-left:20px;} - ` + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + padding-left: 20px; + } + `, ]; } @@ -69,13 +82,20 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { const i18n = this._i18n; return html` <section class="section"> - <p>${i18n.t('demo.provider_description', {id: "root", description: "is the top most in hierarchy"})}</p> + <p>${i18n.t('demo.provider_description', { + id: 'root', + description: 'is the top most in hierarchy', + })}</p> <pre><dbp-provider id="root" root="1" availability="global" ></dbp-provider></pre> <div class="container"> <h1 class="title">${i18n.t('demo.provider')}-Demo</h1> </div> <div class="container"> - <dbp-auth-keycloak subscribe="requested-login-status" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> + <dbp-auth-keycloak subscribe="requested-login-status" lang="${ + this.lang + }" entry-point-url="${ + this.entryPointUrl + }" url="https://auth-dev.tugraz.at/auth" realm="tugraz-vpu" client-id="auth-dev-mw-frontend-local" try-login></dbp-auth-keycloak> <dbp-login-button subscribe="auth" lang="${this.lang}"></dbp-login-button> <dbp-language-select></dbp-language-select> </div> @@ -86,22 +106,40 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { bar="20"> <div class="container"> <h2>${i18n.t('demo.provider')}</h2> - <p>${i18n.t('demo.provider_description', {id: "demo", description: "has only \"border-color\" to offer"})}</p> <pre><dbp-provider id="demo" bc="blue" ></dbp-provider></pre> - <p>${i18n.t('demo.provider_description', {id: "foo-bar", description: "has some values in its store"})}</p> + <p>${i18n.t('demo.provider_description', { + id: 'demo', + description: 'has only "border-color" to offer', + })}</p> <pre><dbp-provider id="demo" bc="blue" ></dbp-provider></pre> + <p>${i18n.t('demo.provider_description', { + id: 'foo-bar', + description: 'has some values in its store', + })}</p> <pre><dbp-provider id="foo-bar" foo="9" bar="20" ></dbp-provider></pre> <h2>${i18n.t('demo.consumer')}</h2> - <p>${i18n.t('demo.consumer_description', {id: "c1", subscriptions: "border-color"})}</p> + <p>${i18n.t('demo.consumer_description', { + id: 'c1', + subscriptions: 'border-color', + })}</p> <pre><dbp-consumer id="c1" subscribe="border-color:bc" ></dbp-consumer></pre> <dbp-consumer id="c1" subscribe="border-color:bc,lang"></dbp-consumer> - <p>${i18n.t('demo.consumer_description', {id: "c2", subscriptions: "foo"})}</p> + <p>${i18n.t('demo.consumer_description', { + id: 'c2', + subscriptions: 'foo', + })}</p> <pre><dbp-consumer id="c2" subscribe="foo:foo" ></dbp-consumer></pre> <dbp-consumer id="c2" subscribe="foo:foo,lang"></dbp-consumer> - <p>${i18n.t('demo.consumer_description', {id: "c3", subscriptions: "availability:status"})}</p> + <p>${i18n.t('demo.consumer_description', { + id: 'c3', + subscriptions: 'availability:status', + })}</p> <p>Local <em>status</em> is provided as <em>availability</em></p> <pre><dbp-consumer id="c3" subscribe="status:availability" border-color="orange" ></dbp-consumer></pre> <dbp-consumer id="c3" subscribe="status:availability,lang" border-color="orange"></dbp-consumer> - <p>${i18n.t('demo.consumer_description', {id: "c4", subscriptions: "unknown-name:status"})}</p> + <p>${i18n.t('demo.consumer_description', { + id: 'c4', + subscriptions: 'unknown-name:status', + })}</p> <p>Remote <em>unknown-name</em> does not exist, the default value is overwritten by <em>undefined</em></i></p> <pre><dbp-consumer id="c4" subscribe="status:unknown-name" border-color="darkgray" ></dbp-consumer></pre> <dbp-consumer id="c4" subscribe="status:unknown-name" border-color="darkgray"></dbp-consumer> @@ -161,13 +199,13 @@ class DemoConsumer extends DBPLitElement { static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, - foo: { type: String }, - bar: { type: String }, - gong: { type: String }, - borderColor: { type: String, attribute: 'border-color' }, - ping: { type: String } + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, + foo: {type: String}, + bar: {type: String}, + gong: {type: String}, + borderColor: {type: String, attribute: 'border-color'}, + ping: {type: String}, }; } @@ -176,8 +214,18 @@ class DemoConsumer extends DBPLitElement { return; } - console.debug('DemoConsumer(' + this.id + ') attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')'); - switch(name) { + console.debug( + 'DemoConsumer(' + + this.id + + ') attributeChangesCallback( ' + + name + + ', ' + + oldValue + + ', ' + + newValue + + ')' + ); + switch (name) { case 'lang': this.lang = newValue; this._i18n.changeLanguage(this.lang); @@ -206,25 +254,37 @@ class DemoConsumer extends DBPLitElement { render() { const i18n = this._i18n; - if (! this.connected) { + if (!this.connected) { return `not connected!`; } console.debug('DemoConsumer(' + this.id + ') render()'); const sum = this.foo + this.bar; return html` - <div style="border: ${this['border-color']} dotted; padding: 10px;"> - <table style="width:200px;"> - <tr style="background-color: #aaa;"> - <th style="text-align: left;">${i18n.t('consumer.item')}</th> - <th style="text-align: right;">${i18n.t('consumer.price')}</th> - </tr> - <tr><td>foo</td><td style="text-align: right;">${this.foo}</td></tr> - <tr><td>bar</td><td style="text-align: right;">${this.bar}</td></tr> - <tr><td>${i18n.t('consumer.sum')}</td><td style="text-align: right;">${sum}</td></tr> - </table> - <p>Status: <b>${this.status}</b></p> - </div> + <div style="border: ${this['border-color']} dotted; padding: 10px;"> + <table style="width:200px;"> + <tr style="background-color: #aaa;"> + <th style="text-align: left;">${i18n.t('consumer.item')}</th> + <th style="text-align: right;">${i18n.t('consumer.price')}</th> + </tr> + <tr> + <td>foo</td> + <td style="text-align: right;">${this.foo}</td> + </tr> + <tr> + <td>bar</td> + <td style="text-align: right;">${this.bar}</td> + </tr> + <tr> + <td>${i18n.t('consumer.sum')}</td> + <td style="text-align: right;">${sum}</td> + </tr> + </table> + <p> + Status: + <b>${this.status}</b> + </p> + </div> `; } } diff --git a/packages/provider/src/demo.js b/packages/provider/src/demo.js index 8425d88d6e1ba87d2786037bb0ac6638091a1d00..b761942fa150d3c4131bf1f69f8cd054b447235c 100644 --- a/packages/provider/src/demo.js +++ b/packages/provider/src/demo.js @@ -1 +1 @@ -import './dbp-provider-demo.js'; \ No newline at end of file +import './dbp-provider-demo.js'; diff --git a/packages/provider/src/i18n.js b/packages/provider/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/provider/src/i18n.js +++ b/packages/provider/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/provider/src/i18n/de/translation.json b/packages/provider/src/i18n/de/translation.json index 650f83a0c7b12b219550dcf82b663ba8ebb5954a..ba6caee81fa88309f997631b741afd05f5004f47 100644 --- a/packages/provider/src/i18n/de/translation.json +++ b/packages/provider/src/i18n/de/translation.json @@ -1,13 +1,13 @@ { - "demo": { - "provider": "Anbieter", - "consumer": "Verbraucher", - "provider_description": "Anbieter \"{{id}}\" {{description}}", - "consumer_description": "Verbraucher \"{{id}}\" abonniert nur {{subscriptions}}" - }, - "consumer": { - "item": "Bezeichnung", - "price": "Preis", - "sum": "Summe" - } + "demo": { + "provider": "Anbieter", + "consumer": "Verbraucher", + "provider_description": "Anbieter \"{{id}}\" {{description}}", + "consumer_description": "Verbraucher \"{{id}}\" abonniert nur {{subscriptions}}" + }, + "consumer": { + "item": "Bezeichnung", + "price": "Preis", + "sum": "Summe" + } } diff --git a/packages/provider/src/i18n/en/translation.json b/packages/provider/src/i18n/en/translation.json index e511b79f6a21db9fe5ea29cf912c4308604ba5ce..f73c4c0806dd843fb7e207f1d3038f6015adc27d 100644 --- a/packages/provider/src/i18n/en/translation.json +++ b/packages/provider/src/i18n/en/translation.json @@ -1,13 +1,13 @@ { - "demo": { - "provider": "Provider", - "consumer": "Consumer", - "provider_description": "Provider \"{{id}}\" {{description}}", - "consumer_description": "Consumer \"{{id}}\" will only subscribe to {{subscriptions}}" - }, - "consumer": { - "item": "Description", - "price": "Price", - "sum": "sum" - } + "demo": { + "provider": "Provider", + "consumer": "Consumer", + "provider_description": "Provider \"{{id}}\" {{description}}", + "consumer_description": "Consumer \"{{id}}\" will only subscribe to {{subscriptions}}" + }, + "consumer": { + "item": "Description", + "price": "Price", + "sum": "sum" + } } diff --git a/packages/provider/src/index.js b/packages/provider/src/index.js index 6f6fd2b3599dd14e85c844a5c7a4de8ac5fd3b9c..cb4dd44b9e4165e3e06fb840b2e0ea67fb41a6ba 100644 --- a/packages/provider/src/index.js +++ b/packages/provider/src/index.js @@ -2,4 +2,4 @@ import {Provider} from './provider.js'; import {Adapter} from './adapter.js'; export {Provider}; -export {Adapter}; \ No newline at end of file +export {Adapter}; diff --git a/packages/provider/src/provider.js b/packages/provider/src/provider.js index 69d4c3a9571e5286109831a8a090bb94fddeeac2..88b388fc4ac4187a2aa3ee853317b8e3e8e74ad9 100644 --- a/packages/provider/src/provider.js +++ b/packages/provider/src/provider.js @@ -1,4 +1,4 @@ -import {Logger} from "@dbp-toolkit/common"; +import {Logger} from '@dbp-toolkit/common'; export class Provider extends HTMLElement { constructor() { @@ -39,69 +39,111 @@ export class Provider extends HTMLElement { const that = this; - this.addEventListener('dbp-subscribe', function (e) { - const name = e.detail.name; - if (that.hasProperty(name) || that.root) { - Logger.debug('Provider(' + that.id + ') eventListener("dbp-subscribe",..) name "' + name + '" found.'); - that.callbackStore.push({name: name, callback: e.detail.callback, sender: e.detail.sender}); - - e.detail.callback(that.getProperty(name)); - e.stopPropagation(); - } - }, false); - - this.addEventListener('dbp-unsubscribe', function (e) { - const name = e.detail.name; - const sender = e.detail.sender; - if (that.hasProperty(name) || that.root) { - Logger.debug('Provider(' + that.id + ') eventListener("dbp-unsubscribe",..) name "' + name + '" found.'); - that.callbackStore.forEach(item => { - if (item.sender === sender && item.name === name) { - const index = that.callbackStore.indexOf(item); - that.callbackStore.splice(index, 1); - Logger.debug('Provider(' + that.id + ') eventListener for name "' + name + '" removed.'); - } - }); - - e.stopPropagation(); - } - }, false); + this.addEventListener( + 'dbp-subscribe', + function (e) { + const name = e.detail.name; + if (that.hasProperty(name) || that.root) { + Logger.debug( + 'Provider(' + + that.id + + ') eventListener("dbp-subscribe",..) name "' + + name + + '" found.' + ); + that.callbackStore.push({ + name: name, + callback: e.detail.callback, + sender: e.detail.sender, + }); + + e.detail.callback(that.getProperty(name)); + e.stopPropagation(); + } + }, + false + ); + + this.addEventListener( + 'dbp-unsubscribe', + function (e) { + const name = e.detail.name; + const sender = e.detail.sender; + if (that.hasProperty(name) || that.root) { + Logger.debug( + 'Provider(' + + that.id + + ') eventListener("dbp-unsubscribe",..) name "' + + name + + '" found.' + ); + that.callbackStore.forEach((item) => { + if (item.sender === sender && item.name === name) { + const index = that.callbackStore.indexOf(item); + that.callbackStore.splice(index, 1); + Logger.debug( + 'Provider(' + + that.id + + ') eventListener for name "' + + name + + '" removed.' + ); + } + }); + + e.stopPropagation(); + } + }, + false + ); // listen to property changes - this.addEventListener('dbp-set-property', function (e) { - const name = e.detail.name; - const value = e.detail.value; - - if (that.hasProperty(name) || that.root) { - Logger.debug('Provider(' + that.id + ') eventListener("dbp-set-property",..) name "' + name + '" found.'); - that.setProperty(name, value); - - that.callbackStore.forEach(item => { - if (item.name === name) { - item.callback(value); - } - }); - - e.stopPropagation(); - } - }, false); + this.addEventListener( + 'dbp-set-property', + function (e) { + const name = e.detail.name; + const value = e.detail.value; + + if (that.hasProperty(name) || that.root) { + Logger.debug( + 'Provider(' + + that.id + + ') eventListener("dbp-set-property",..) name "' + + name + + '" found.' + ); + that.setProperty(name, value); + + that.callbackStore.forEach((item) => { + if (item.name === name) { + item.callback(value); + } + }); + + e.stopPropagation(); + } + }, + false + ); // Options for the observer (which mutations to observe) - const config = { attributes: true, childList: false, subtree: false }; + const config = {attributes: true, childList: false, subtree: false}; // Callback function to execute when mutations are observed - const callback = function(mutationsList, observer) { + const callback = function (mutationsList, observer) { // Use traditional 'for loops' for IE 11 - for(const mutation of mutationsList) { + for (const mutation of mutationsList) { if (mutation.type === 'attributes') { const name = mutation.attributeName; const value = that.getAttribute(name); if (that.hasPropertyChanged(name, value)) { - Logger.debug('Provider (' + that.id + ') observed attribute "' + name + '" changed'); + Logger.debug( + 'Provider (' + that.id + ') observed attribute "' + name + '" changed' + ); that.setProperty(name, value); - that.callbackStore.forEach(item => { + that.callbackStore.forEach((item) => { if (item.name === name) { item.callback(value); } @@ -120,13 +162,21 @@ export class Provider extends HTMLElement { // get all *not observed* attributes if (this.hasAttributes()) { const attrs = this.attributes; - for(let i = attrs.length - 1; i >= 0; i--) { + for (let i = attrs.length - 1; i >= 0; i--) { if (['id', 'class', 'style', 'data-tag-name'].includes(attrs[i].name)) { continue; } this.setProperty(attrs[i].name, attrs[i].value); - Logger.debug('Provider (' + that.id + ') found attribute "' + attrs[i].name + '" = "' + attrs[i].value + '"'); + Logger.debug( + 'Provider (' + + that.id + + ') found attribute "' + + attrs[i].name + + '" = "' + + attrs[i].value + + '"' + ); } } } diff --git a/packages/qr-code-scanner/.eslintrc.json b/packages/qr-code-scanner/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/qr-code-scanner/.eslintrc.json +++ b/packages/qr-code-scanner/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/qr-code-scanner/.prettierignore b/packages/qr-code-scanner/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/qr-code-scanner/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/qr-code-scanner/.prettierrc.json b/packages/qr-code-scanner/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/qr-code-scanner/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/qr-code-scanner/i18next-scanner.config.js b/packages/qr-code-scanner/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/qr-code-scanner/i18next-scanner.config.js +++ b/packages/qr-code-scanner/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/qr-code-scanner/package.json b/packages/qr-code-scanner/package.json index f9911351ab045088ac07abba607025aa67ebf883..1a5d92734e13eca3cfcb2229bb2e0acf6bb323cf 100644 --- a/packages/qr-code-scanner/package.json +++ b/packages/qr-code-scanner/package.json @@ -1,59 +1,63 @@ { - "name": "@dbp-toolkit/qr-code-scanner", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/qr-code-scanner", - "version": "0.2.4", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/qr-code-scanner" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.0.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2", - "selfsigned": "^2.0.0" - }, - "dependencies": { - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "async-mutex": "^0.3.0", - "lit": "^2.0.0", - "qr-scanner": "^1.2.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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/qr-code-scanner", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/qr-code-scanner", + "version": "0.2.4", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/qr-code-scanner" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.0.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2", + "selfsigned": "^2.0.0" + }, + "dependencies": { + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "async-mutex": "^0.3.0", + "lit": "^2.0.0", + "qr-scanner": "^1.2.0" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/qr-code-scanner/rollup.config.js b/packages/qr-code-scanner/rollup.config.js index 45dc4d718e7b97257dedf12ec4238806b16ba171..ba20556ce08b056de8dfc2fca691e776f843a912 100644 --- a/packages/qr-code-scanner/rollup.config.js +++ b/packages/qr-code-scanner/rollup.config.js @@ -2,18 +2,18 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url"; +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; -import fs from "fs"; -import selfsigned from "selfsigned"; -import {getPackagePath, getDistPath} from "../../rollup.utils"; +import fs from 'fs'; +import selfsigned from 'selfsigned'; +import {getPackagePath, getDistPath} from '../../rollup.utils'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); const USE_HTTPS = true; @@ -29,24 +29,26 @@ function generateTLSConfig() { return { key: fs.readFileSync('.cert/server.key'), - cert: fs.readFileSync('.cert/server.cert') - } + cert: fs.readFileSync('.cert/server.cert'), + }; } - -export default (async () => { +export default async () => { return { - input: (build != 'test') ? ['src/dbp-qr-code-scanner.js', 'src/dbp-qr-code-scanner-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-qr-code-scanner.js', 'src/dbp-qr-code-scanner-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), @@ -54,23 +56,31 @@ export default (async () => { url({ limit: 0, emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, {src: 'assets/favicon.ico', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, - {src: await getPackagePath('qr-scanner', 'qr-scanner-worker.*'), dest: 'dist/' + await getDistPath(pkg.name)}, - ] + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, + { + src: await getPackagePath('qr-scanner', 'qr-scanner-worker.*'), + dest: 'dist/' + (await getDistPath(pkg.name)), + }, + ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({ - contentBase: 'dist', - host: '127.0.0.1', - port: 8002, - https: USE_HTTPS ? generateTLSConfig() : false - }) : false - ] - } -}); + process.env.ROLLUP_WATCH === 'true' + ? serve({ + contentBase: 'dist', + host: '127.0.0.1', + port: 8002, + https: USE_HTTPS ? generateTLSConfig() : false, + }) + : false, + ], + }; +}; diff --git a/packages/qr-code-scanner/src/dbp-qr-code-scanner-demo.js b/packages/qr-code-scanner/src/dbp-qr-code-scanner-demo.js index 4acc903cece7cbf9013cb088398b8ad137c68bf6..248b91e2d8aa75f77eee8931084d6d0e2586b885 100644 --- a/packages/qr-code-scanner/src/dbp-qr-code-scanner-demo.js +++ b/packages/qr-code-scanner/src/dbp-qr-code-scanner-demo.js @@ -2,7 +2,7 @@ import {createInstance} from './i18n'; import {css, html, LitElement} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from '@dbp-toolkit/common/utils'; -import * as commonStyles from "@dbp-toolkit/common/styles"; +import * as commonStyles from '@dbp-toolkit/common/styles'; import {QrCodeScanner} from './qr-code-scanner.js'; export class QrCodeScannerDemo extends ScopedElementsMixin(LitElement) { @@ -16,16 +16,16 @@ export class QrCodeScannerDemo extends ScopedElementsMixin(LitElement) { return { 'dbp-qr-code-scanner': QrCodeScanner, }; - } + } static get properties() { return { - lang: { type: String }, + lang: {type: String}, }; } update(changedProperties) { - if (changedProperties.has("lang")) { + if (changedProperties.has('lang')) { this._i18n.changeLanguage(this.lang); } super.update(changedProperties); @@ -33,16 +33,16 @@ export class QrCodeScannerDemo extends ScopedElementsMixin(LitElement) { static get styles() { // language=css - return css` + return css` ${commonStyles.getThemeCSS()} ${commonStyles.getGeneralCSS()} ${commonStyles.getButtonCSS()} - h1{ + h1 { margin-bottom: 20px; } - - .section{ + + .section { margin-bottom: 50px; } `; @@ -50,14 +50,18 @@ export class QrCodeScannerDemo extends ScopedElementsMixin(LitElement) { render() { return html` - <section class="section"> + <section class="section"> <div class="container"> <h1 class="title">QR-Code-Scanner-Demo</h1> </div> <div class="container"> <div class="columns is-centered"> <div class="column"> - <dbp-qr-code-scanner @code-detected="${(e) => console.log(e)}" @scan-started="${(e) => console.log(e)}" show-output lang="${this.lang}"></dbp-qr-code-scanner> + <dbp-qr-code-scanner + @code-detected="${(e) => console.log(e)}" + @scan-started="${(e) => console.log(e)}" + show-output + lang="${this.lang}"></dbp-qr-code-scanner> </div> </div> </div> diff --git a/packages/qr-code-scanner/src/i18n.js b/packages/qr-code-scanner/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/qr-code-scanner/src/i18n.js +++ b/packages/qr-code-scanner/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/qr-code-scanner/src/i18n/de/translation.json b/packages/qr-code-scanner/src/i18n/de/translation.json index 652c7eec581270a762169ee1e7115c00b779e48e..fc2732580ea44a604508491b5159bc098b542f54 100644 --- a/packages/qr-code-scanner/src/i18n/de/translation.json +++ b/packages/qr-code-scanner/src/i18n/de/translation.json @@ -1,14 +1,14 @@ { - "no-camera-access": "Zugriff auf Kamera nicht möglich.", - "check-access": "Bitte stellen Sie sicher, dass eine Webcam oder Kamera aktiviert ist und überprüfen Sie ob Ihr Browser die notwendigen Berechtigungen besitzt.", - "loading-video": "Video laden ...", - "no-qr-detected": "Kein QR-Code erkannt.", - "no-support": "Ihr Browser unterstützt keine Videoaufnahmen.", - "no-ios-support": "Ihr Browser unterstützt keine Videoaufnahmen. Bitte verwenden Sie Safari.", - "data": "Inhalt", - "camera": "Kamera ", - "front-camera": "Vordere Kamera", - "back-camera": "Rückseitige Kamera", - "start-scan": "Scannen starten", - "stop-scan": "Scannen stoppen" + "no-camera-access": "Zugriff auf Kamera nicht möglich.", + "check-access": "Bitte stellen Sie sicher, dass eine Webcam oder Kamera aktiviert ist und überprüfen Sie ob Ihr Browser die notwendigen Berechtigungen besitzt.", + "loading-video": "Video laden ...", + "no-qr-detected": "Kein QR-Code erkannt.", + "no-support": "Ihr Browser unterstützt keine Videoaufnahmen.", + "no-ios-support": "Ihr Browser unterstützt keine Videoaufnahmen. Bitte verwenden Sie Safari.", + "data": "Inhalt", + "camera": "Kamera ", + "front-camera": "Vordere Kamera", + "back-camera": "Rückseitige Kamera", + "start-scan": "Scannen starten", + "stop-scan": "Scannen stoppen" } diff --git a/packages/qr-code-scanner/src/i18n/en/translation.json b/packages/qr-code-scanner/src/i18n/en/translation.json index cb653c89b4a8f597518943fa7142720cb52695a5..e2786c53ef0b4c0c54605849457a340f74fb48fe 100644 --- a/packages/qr-code-scanner/src/i18n/en/translation.json +++ b/packages/qr-code-scanner/src/i18n/en/translation.json @@ -1,14 +1,14 @@ { - "no-camera-access": "Unable to access video stream.", - "check-access": "Please make sure that a webcam or camera is activated and check whether your browser has the necessary authorizations.", - "loading-video": "⌛ Loading video...", - "no-qr-detected": "No QR code detected.", - "no-support": "Your browser does not support video recording.", - "no-ios-support": "Your browser does not support video recording. Please use Safari.", - "data": "Data", - "camera": "Camera ", - "front-camera": "Frontcamera", - "back-camera": "Backcamera", - "start-scan": "Start scan", - "stop-scan": "Stop scan" + "no-camera-access": "Unable to access video stream.", + "check-access": "Please make sure that a webcam or camera is activated and check whether your browser has the necessary authorizations.", + "loading-video": "⌛ Loading video...", + "no-qr-detected": "No QR code detected.", + "no-support": "Your browser does not support video recording.", + "no-ios-support": "Your browser does not support video recording. Please use Safari.", + "data": "Data", + "camera": "Camera ", + "front-camera": "Frontcamera", + "back-camera": "Backcamera", + "start-scan": "Start scan", + "stop-scan": "Stop scan" } diff --git a/packages/qr-code-scanner/src/index.js b/packages/qr-code-scanner/src/index.js index 11bdb409e8166acd2988abf24aad95ed2e468fab..4e722c43212845e5ab9870d822d08eb423ebdc56 100644 --- a/packages/qr-code-scanner/src/index.js +++ b/packages/qr-code-scanner/src/index.js @@ -1,3 +1,3 @@ import {QrCodeScanner} from './qr-code-scanner.js'; -export {QrCodeScanner}; \ No newline at end of file +export {QrCodeScanner}; diff --git a/packages/qr-code-scanner/src/qr-code-scanner.js b/packages/qr-code-scanner/src/qr-code-scanner.js index 6849679c02f099852bde46a6c076594e9869e7b6..a3605846f9082ab5a5482fbb510c743e9988e872 100644 --- a/packages/qr-code-scanner/src/qr-code-scanner.js +++ b/packages/qr-code-scanner/src/qr-code-scanner.js @@ -10,8 +10,6 @@ import {Mutex} from 'async-mutex'; import {name as pkgName} from './../package.json'; import {getIconSVGURL} from '@dbp-toolkit/common'; - - /** * Returns the ID for the most important device * @@ -19,9 +17,10 @@ import {getIconSVGURL} from '@dbp-toolkit/common'; * @returns {string|null} the ID */ function getPrimaryDevice(devices) { - if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { - if (devices.has('environment')) - return 'environment'; + if ( + /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + ) { + if (devices.has('environment')) return 'environment'; } if (devices.size) { return Array.from(devices)[0][0]; @@ -39,26 +38,34 @@ function getPrimaryDevice(devices) { */ async function getVideoDevices(i18n) { let devices_map = new Map(); - if (navigator.mediaDevices - && navigator.mediaDevices.enumerateDevices - && navigator.mediaDevices.getUserMedia) { - + if ( + navigator.mediaDevices && + navigator.mediaDevices.enumerateDevices && + navigator.mediaDevices.getUserMedia + ) { let devices; try { devices = await navigator.mediaDevices.enumerateDevices(); } catch (err) { - console.log(err.name + ": " + err.message); + console.log(err.name + ': ' + err.message); return devices_map; } for (let device of devices) { if (device.kind === 'videoinput') { let id = device.deviceId; - if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { + if ( + /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + navigator.userAgent + ) + ) { devices_map.set('environment', i18n.t('back-camera')); devices_map.set('user', i18n.t('front-camera')); } else { - devices_map.set(id ? id : true, device.label || i18n.t('camera') + (devices_map.size + 1)); + devices_map.set( + id ? id : true, + device.label || i18n.t('camera') + (devices_map.size + 1) + ); } } } @@ -75,7 +82,9 @@ async function getVideoDevices(i18n) { * @returns {object|null} a video element or null */ function checkIosMobileSupport(devices_map) { - return /(iPhone|iPad|iPod).*(CriOS|FxiOS|OPT|EdgiOS|YaBrowser|AlohaBrowser)/i.test(navigator.userAgent); + return /(iPhone|iPad|iPod).*(CriOS|FxiOS|OPT|EdgiOS|YaBrowser|AlohaBrowser)/i.test( + navigator.userAgent + ); } /** @@ -83,26 +92,25 @@ function checkIosMobileSupport(devices_map) { * @returns {object|null} a video element or null */ async function createVideoElement(deviceId) { - let videoId = deviceId; - let constraint = { video: { deviceId: videoId } }; - if ( (videoId === 'environment' || videoId === '') ) { - console.log("vid:", videoId); - constraint = { video: { facingMode: "environment" } }; - } else if ( videoId === 'user' ) { - console.log("vid2:", videoId); - constraint = { video: { facingMode: "user", mirrored: true } }; + let constraint = {video: {deviceId: videoId}}; + if (videoId === 'environment' || videoId === '') { + console.log('vid:', videoId); + constraint = {video: {facingMode: 'environment'}}; + } else if (videoId === 'user') { + console.log('vid2:', videoId); + constraint = {video: {facingMode: 'user', mirrored: true}}; } let stream = null; try { stream = await navigator.mediaDevices.getUserMedia(constraint); - } catch(e) { + } catch (e) { console.log(e); } if (stream !== null) { - let video = document.createElement("video"); + let video = document.createElement('video'); video.srcObject = stream; return video; } @@ -113,27 +121,36 @@ async function createVideoElement(deviceId) { class QRScanner { constructor() { this._engine = null; - this._canvas = document.createElement("canvas"); + this._canvas = document.createElement('canvas'); this._scanner = null; } async scan(canvas, x, y, width, height) { - if (this._scanner === null) { + if (this._scanner === null) { this._scanner = (await import('qr-scanner')).default; - this._scanner.WORKER_PATH = commonUtils.getAssetURL(pkgName, 'qr-scanner-worker.min.js'); + this._scanner.WORKER_PATH = commonUtils.getAssetURL( + pkgName, + 'qr-scanner-worker.min.js' + ); } if (this._engine === null) { this._engine = await this._scanner.createQrEngine(this._scanner.WORKER_PATH); } try { - return {data: await this._scanner.scanImage(canvas, {x: x, y: y, width: width, height: height}, this._engine, this._canvas)}; + return { + data: await this._scanner.scanImage( + canvas, + {x: x, y: y, width: width, height: height}, + this._engine, + this._canvas + ), + }; } catch (e) { return null; } } } - export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); @@ -168,17 +185,17 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { static get properties() { return { - lang: { type: String }, - showOutput: { type: Boolean, attribute: 'show-output' }, - stopScan: { type: Boolean, attribute: 'stop-scan' }, - matchRegex: { type: String, attribute: 'match-regex' }, - _activeCamera: { type: String, attribute: false }, - _loading: { type: Boolean, attribute: false }, - _devices: { type: Map, attribute: false}, - _loadingMessage: { type: String, attribute: false }, - _outputData: { type: String, attribute: false }, - _askPermission: { type: Boolean, attribute: false }, - _videoRunning: { type: Boolean, attribute: false }, + lang: {type: String}, + showOutput: {type: Boolean, attribute: 'show-output'}, + stopScan: {type: Boolean, attribute: 'stop-scan'}, + matchRegex: {type: String, attribute: 'match-regex'}, + _activeCamera: {type: String, attribute: false}, + _loading: {type: Boolean, attribute: false}, + _devices: {type: Map, attribute: false}, + _loadingMessage: {type: String, attribute: false}, + _outputData: {type: String, attribute: false}, + _askPermission: {type: Boolean, attribute: false}, + _videoRunning: {type: Boolean, attribute: false}, }; } @@ -210,7 +227,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { - case "lang": + case 'lang': this._i18n.changeLanguage(this.lang); break; } @@ -238,15 +255,19 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { console.assert(this._lock.isLocked()); await this.updateComplete; - let targetCanvas = this._("#canvas"); - let targetvideo = this._("#video"); - let canvasElement = document.createElement("canvas"); + let targetCanvas = this._('#canvas'); + let targetvideo = this._('#video'); + let canvasElement = document.createElement('canvas'); let firstDrawDone = false; this._askPermission = true; - this._loadingMessage = html` ${i18n.t('no-camera-access')} <br> ${i18n.t('check-access')}`; + this._loadingMessage = html` + ${i18n.t('no-camera-access')} + <br /> + ${i18n.t('check-access')} + `; let video = await createVideoElement(this._activeCamera); - if ( video !== null ) { + if (video !== null) { targetvideo.appendChild(video); } this._askPermission = false; @@ -264,7 +285,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { // draw into a temporary canvas first canvasElement.height = video.videoHeight; canvasElement.width = video.videoWidth; - let canvas = canvasElement.getContext("2d"); + let canvas = canvasElement.getContext('2d'); canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height); let maskWidth = canvasElement.width; @@ -272,46 +293,55 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { let maskStartX = 0; let maskStartY = 0; - let maxSize = canvasElement.width > canvasElement.height ? canvasElement.height/4 * 3 : canvasElement.width/4 * 3; + let maxSize = + canvasElement.width > canvasElement.height + ? (canvasElement.height / 4) * 3 + : (canvasElement.width / 4) * 3; console.assert(maxSize <= canvasElement.width && maxSize <= canvasElement.height); maskWidth = maxSize; maskHeight = maxSize; - maskStartX = canvasElement.width/2 - maskWidth/2; - maskStartY = canvasElement.height/2 - maskHeight/2; + maskStartX = canvasElement.width / 2 - maskWidth / 2; + maskStartY = canvasElement.height / 2 - maskHeight / 2; let lastVideo = video; if (!detectorRunning) { detectorRunning = true; - detector.scan(canvasElement, maskStartX, maskStartY, maskWidth, maskHeight).then((code) => { - detectorRunning = false; - // if we got restarted then the video element is new, so stop then. - if (lastVideo !== this._videoElement) - return; - lastCode = code; - - if (code) { - if (lastSentData !== code.data) { - this._outputData = code.data; - this.dispatchEvent(new CustomEvent("code-detected", - {bubbles: true, composed: true, detail: {'code': code.data}})); + detector + .scan(canvasElement, maskStartX, maskStartY, maskWidth, maskHeight) + .then((code) => { + detectorRunning = false; + // if we got restarted then the video element is new, so stop then. + if (lastVideo !== this._videoElement) return; + lastCode = code; + + if (code) { + if (lastSentData !== code.data) { + this._outputData = code.data; + this.dispatchEvent( + new CustomEvent('code-detected', { + bubbles: true, + composed: true, + detail: {code: code.data}, + }) + ); + } + lastSentData = code.data; + } else { + this._outputData = null; + lastSentData = null; } - lastSentData = code.data; - } else { - this._outputData = null; - lastSentData = null; - } - }); + }); } let matched = lastCode ? lastCode.data.match(this.matchRegex) !== null : false; //draw mask canvas.beginPath(); - canvas.fillStyle = "#0000006e"; - canvas.moveTo(0,0); + canvas.fillStyle = '#0000006e'; + canvas.moveTo(0, 0); canvas.lineTo(0, canvasElement.height); - canvas.lineTo( canvasElement.width, canvasElement.height); - canvas.lineTo( canvasElement.width,0); + canvas.lineTo(canvasElement.width, canvasElement.height); + canvas.lineTo(canvasElement.width, 0); canvas.rect(maskStartX, maskStartY, maskWidth, maskHeight); canvas.fill(); @@ -325,23 +355,55 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { } let borderWidth = Math.max(maskWidth, maskHeight) / 50; - canvas.moveTo(maskStartX,maskStartY); - canvas.rect(maskStartX, maskStartY, maskWidth/3, borderWidth); - canvas.rect(maskStartX, maskStartY, borderWidth, maskHeight/3); - canvas.rect(maskStartX + maskWidth/3*2, maskStartY, maskWidth/3, borderWidth); - canvas.rect(maskStartX + maskWidth - borderWidth, maskStartY, borderWidth, maskHeight/3); - canvas.rect(maskStartX, maskStartY + maskHeight - borderWidth, maskWidth/3, borderWidth); - canvas.rect(maskStartX, maskStartY + maskHeight/3*2, borderWidth, maskHeight/3); - canvas.rect(maskStartX + maskWidth/3*2, maskStartY + maskHeight - borderWidth, maskWidth/3, borderWidth); - canvas.rect(maskStartX + maskWidth - borderWidth, maskStartY + maskHeight/3*2, borderWidth, maskHeight/3); + canvas.moveTo(maskStartX, maskStartY); + canvas.rect(maskStartX, maskStartY, maskWidth / 3, borderWidth); + canvas.rect(maskStartX, maskStartY, borderWidth, maskHeight / 3); + canvas.rect( + maskStartX + (maskWidth / 3) * 2, + maskStartY, + maskWidth / 3, + borderWidth + ); + canvas.rect( + maskStartX + maskWidth - borderWidth, + maskStartY, + borderWidth, + maskHeight / 3 + ); + canvas.rect( + maskStartX, + maskStartY + maskHeight - borderWidth, + maskWidth / 3, + borderWidth + ); + canvas.rect( + maskStartX, + maskStartY + (maskHeight / 3) * 2, + borderWidth, + maskHeight / 3 + ); + canvas.rect( + maskStartX + (maskWidth / 3) * 2, + maskStartY + maskHeight - borderWidth, + maskWidth / 3, + borderWidth + ); + canvas.rect( + maskStartX + maskWidth - borderWidth, + maskStartY + (maskHeight / 3) * 2, + borderWidth, + maskHeight / 3 + ); canvas.fill(); targetCanvas.height = canvasElement.height; targetCanvas.width = canvasElement.width; - targetCanvas.getContext("2d").drawImage(canvasElement, 0, 0); + targetCanvas.getContext('2d').drawImage(canvasElement, 0, 0); if (!firstDrawDone) { - this.dispatchEvent(new CustomEvent("scan-started", {bubbles: true, composed: true})); + this.dispatchEvent( + new CustomEvent('scan-started', {bubbles: true, composed: true}) + ); firstDrawDone = true; } } @@ -350,7 +412,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { }; if (video !== null) { - video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen + video.setAttribute('playsinline', true); // required to tell iOS safari we don't want fullscreen video.play(); this._videoRunning = true; @@ -371,7 +433,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { this._activeCamera = e.srcElement.value; await this.stopScanning(); await this.startScanning(); - console.log("Changed Media"); + console.log('Changed Media'); } /** @@ -383,7 +445,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { try { if (this._videoElement !== null) { let video = this._videoElement; - video.srcObject.getTracks().forEach(function(track) { + video.srcObject.getTracks().forEach(function (track) { track.stop(); }); this._videoElement = null; @@ -416,39 +478,39 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { text-align: center; padding: 40px; } - + .wrapper-msg { width: 100%; display: flex; justify-content: center; align-items: baseline; } - + #canvas { margin-top: 2rem; max-height: calc(100vh - 100px); max-width: 100%; } - + .output { - margin-top: 20px; - background: var(--dbp-text-muted); - color: var(--dbp-text); - padding: 10px; - padding-bottom: 0; + margin-top: 20px; + background: var(--dbp-text-muted); + color: var(--dbp-text); + padding: 10px; + padding-bottom: 0; } - + .output div { - padding-bottom: 10px; - word-wrap: break-word; + padding-bottom: 10px; + word-wrap: break-word; } - .spinner{ + .spinner { margin-right: 10px; font-size: 0.7em; } - - #videoSource{ + + #videoSource { padding-bottom: calc(0.375em - 2px); padding-left: 0.75em; padding-right: 1.75em; @@ -456,36 +518,36 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { background-position-x: calc(100% - 0.4rem); font-size: inherit; } - + #videoSource:hover { - background: calc(100% - 0.2rem) center no-repeat url("${unsafeCSS(getIconSVGURL('chevron-down'))}"); + background: calc(100% - 0.2rem) center no-repeat + url('${unsafeCSS(getIconSVGURL('chevron-down'))}'); color: var(--dbp-text); background-position-x: calc(100% - 0.4rem); background-size: auto 45%; } - - select:not(.select)#videoSource{ + + select:not(.select)#videoSource { background-size: auto 45%; } - - .border{ + + .border { margin-top: 2rem; padding-top: 2rem; border-top: var(--dbp-border); } - - #video video, #video{ + + #video video, + #video { height: 0px; width: 0px; opacity: 0; } - - @media only screen - and (orientation: portrait) - and (max-width: 768px) { - .button-wrapper{ + + @media only screen and (orientation: portrait) and (max-width: 768px) { + .button-wrapper { display: flex; - justify-content: space-between; + justify-content: space-between; } } `; @@ -495,46 +557,69 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { const i18n = this._i18n; let hasDevices = this._devices.size > 0; let showCanvas = this._videoRunning && !this._askPermission && !this._loading; - let noSupportString = checkIosMobileSupport(this._devices) ? i18n.t('no-ios-support') : i18n.t('no-support'); + let noSupportString = checkIosMobileSupport(this._devices) + ? i18n.t('no-ios-support') + : i18n.t('no-support'); return html` <div class="columns"> <div class="column"> - <div class="${classMap({hidden: !hasDevices})}"> - - <div class="button-wrapper"> - <button class="start button is-primary ${classMap({hidden: this._videoRunning})}" @click="${() => this.startScanning()}" title="${i18n.t('start-scan')}">${i18n.t('start-scan')}</button> - <button class="stop button is-primary ${classMap({hidden: !this._videoRunning})}" @click="${() => this.stopScanning()}" title="${i18n.t('stop-scan')}">${i18n.t('stop-scan')}</button> - + <button + class="start button is-primary ${classMap({ + hidden: this._videoRunning, + })}" + @click="${() => this.startScanning()}" + title="${i18n.t('start-scan')}"> + ${i18n.t('start-scan')} + </button> + <button + class="stop button is-primary ${classMap({ + hidden: !this._videoRunning, + })}" + @click="${() => this.stopScanning()}" + title="${i18n.t('stop-scan')}"> + ${i18n.t('stop-scan')} + </button> + <select id="videoSource" class="button" @change=${this._onUpdateSource}> - ${Array.from(this._devices).map(item => html`<option value="${item[0]}">${item[1]}</option>`)} + ${Array.from(this._devices).map( + (item) => + html` + <option value="${item[0]}">${item[1]}</option> + ` + )} </select> - </div> - + <div id="loadingMessage" class="${classMap({hidden: showCanvas})}"> <div class="wrapper-msg"> - <dbp-mini-spinner class="spinner ${classMap({hidden: !this._loading})}"></dbp-mini-spinner> + <dbp-mini-spinner + class="spinner ${classMap({ + hidden: !this._loading, + })}"></dbp-mini-spinner> <div class="loadingMsg">${this._loadingMessage}</div> </div> - </div> - <canvas id="canvas" class="${classMap({hidden: !showCanvas})}"></canvas> - <div id="video"></div> + </div> + <canvas id="canvas" class="${classMap({hidden: !showCanvas})}"></canvas> + <div id="video"></div> <div class="output ${classMap({hidden: !(this.showOutput && showCanvas)})}"> - ${ (this._outputData !== null) ? html` - <div><b>${i18n.t('data')}:</b> <span>${this._outputData}</span></div> - ` : html` - <div>${i18n.t('no-qr-detected')}</div> - `} + ${this._outputData !== null + ? html` + <div> + <b>${i18n.t('data')}:</b> + <span>${this._outputData}</span> + </div> + ` + : html` + <div>${i18n.t('no-qr-detected')}</div> + `} </div> </div> - <div class="${classMap({hidden: hasDevices})}"> - ${noSupportString} - </div> + <div class="${classMap({hidden: hasDevices})}">${noSupportString}</div> </div> </div> `; } -} \ No newline at end of file +} diff --git a/packages/qr-code-scanner/test/unit.js b/packages/qr-code-scanner/test/unit.js index 9631ba2ad818fb5ac2ef047948bdf03747ea0c4c..2c1b29876ba615e2fff80fb9e26aae6cf75d52c7 100644 --- a/packages/qr-code-scanner/test/unit.js +++ b/packages/qr-code-scanner/test/unit.js @@ -3,19 +3,19 @@ import {assert} from '@esm-bundle/chai'; import '../src/dbp-qr-code-scanner'; suite('dbp-qr-code-scanner basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-qr-code-scanner'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-qr-code-scanner'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/theme-switcher/.eslintrc.json b/packages/theme-switcher/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/theme-switcher/.eslintrc.json +++ b/packages/theme-switcher/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/theme-switcher/.prettierignore b/packages/theme-switcher/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/theme-switcher/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/theme-switcher/.prettierrc.json b/packages/theme-switcher/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/theme-switcher/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/theme-switcher/i18next-scanner.config.js b/packages/theme-switcher/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/theme-switcher/i18next-scanner.config.js +++ b/packages/theme-switcher/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/theme-switcher/package.json b/packages/theme-switcher/package.json index 51d74bc59a597b597d3e5c130716e31f79c6661e..b3dbf51078b0755bee410e4bd922082ae77b2a35 100644 --- a/packages/theme-switcher/package.json +++ b/packages/theme-switcher/package.json @@ -1,58 +1,62 @@ { - "name": "@dbp-toolkit/theme-switcher", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/theme-switcher", - "version": "0.0.1", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/theme-switcher" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.0.2", - "@rollup/plugin-node-resolve": "^13.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.0", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "i18next": "^21.4.2", - "jszip": "^3.5.0", - "lit": "^2.0.0", - "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", - "lint": "eslint ." - } + "name": "@dbp-toolkit/theme-switcher", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/theme-switcher", + "version": "0.0.1", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/theme-switcher" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.0.2", + "@rollup/plugin-node-resolve": "^13.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.0", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "i18next": "^21.4.2", + "jszip": "^3.5.0", + "lit": "^2.0.0", + "material-design-icons-svg": "^3.0.0" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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", + "lint": "eslint ." + } } diff --git a/packages/theme-switcher/rollup.config.js b/packages/theme-switcher/rollup.config.js index 940641a06773f564ce042d646862b5e6cd36742e..4f7e4a60fc3f3f41e5841dcf3cba928deb548270 100644 --- a/packages/theme-switcher/rollup.config.js +++ b/packages/theme-switcher/rollup.config.js @@ -2,46 +2,54 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; import del from 'rollup-plugin-delete'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; -import path from "path"; +import path from 'path'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +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 (async () => { return { - input: (build !== 'test') ? ['src/demo.js', 'src/dbp-theme-switcher.js'] : glob.sync('test/**/*.js'), + input: + build !== 'test' + ? ['src/demo.js', 'src/dbp-theme-switcher.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve({browser: true}), commonjs(), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, {src: 'assets/favicon.ico', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, ], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; -})(); \ No newline at end of file +})(); diff --git a/packages/theme-switcher/src/dbp-theme-switcher.js b/packages/theme-switcher/src/dbp-theme-switcher.js index 5bec62ccb59830681282cdc4cea3e0c570dd85e3..a1eeb9824fd5390b6308b3d0b8a4cebd03dfb0a3 100644 --- a/packages/theme-switcher/src/dbp-theme-switcher.js +++ b/packages/theme-switcher/src/dbp-theme-switcher.js @@ -1,4 +1,4 @@ -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {ThemeSwitcher} from './theme-switcher'; commonUtils.defineCustomElement('dbp-theme-switcher', ThemeSwitcher); diff --git a/packages/theme-switcher/src/demo.js b/packages/theme-switcher/src/demo.js index 013fff6e74c3ab0778e47835afaaa5918e120538..56e65522b8eb86e37e8ba0df12d23a2d56ef739f 100644 --- a/packages/theme-switcher/src/demo.js +++ b/packages/theme-switcher/src/demo.js @@ -1,7 +1,7 @@ import {createInstance} from './i18n'; import {html, LitElement} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; -import {ThemeSwitcher} from "./theme-switcher"; +import {ThemeSwitcher} from './theme-switcher'; import * as commonUtils from '@dbp-toolkit/common/utils'; export class ThemeSwitcherDemo extends ScopedElementsMixin(LitElement) { @@ -16,13 +16,13 @@ export class ThemeSwitcherDemo extends ScopedElementsMixin(LitElement) { static get scopedElements() { return { - 'dbp-theme-switcher': ThemeSwitcher, + 'dbp-theme-switcher': ThemeSwitcher, }; } static get properties() { return { - lang: { type: String } + lang: {type: String}, }; } @@ -32,7 +32,7 @@ export class ThemeSwitcherDemo extends ScopedElementsMixin(LitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -40,13 +40,12 @@ export class ThemeSwitcherDemo extends ScopedElementsMixin(LitElement) { super.update(changedProperties); } - render() { const i18n = this._i18n; return html` <style> - .light-theme{ + .light-theme { /* You must not fill out all vars, if they are not filled in, it would take an appropriate default value */ --dbp-override-base: white; --dbp-override-base-inverted: black; @@ -72,10 +71,9 @@ export class ThemeSwitcherDemo extends ScopedElementsMixin(LitElement) { --dbp-override-hover-base: black; --dbp-override-hover-text: white; - } - .dark-theme{ + .dark-theme { /* If you don't want to use an additional theme, then delete the "themes" attribute */ /* You have to fill out all vars, if you want to use the dark theme, the default values would be the light theme. */ @@ -99,27 +97,25 @@ export class ThemeSwitcherDemo extends ScopedElementsMixin(LitElement) { --dbp-override-border: 1px solid white; --dbp-override-border-radius: 0px; - /* Remove hover vars if you don't want a hover effect */ --dbp-override-hover-base: white; --dbp-override-hover-text: #151515; - } </style> - + <section class="section"> <div class="content"> <h1 class="title">${i18n.t('demo-title')}</h1> <p>${i18n.t('intro')}</p> </div> <div class="content"> - <dbp-theme-switcher themes='[{"class": "light-theme", "icon": "sun", "name": "Light Mode"}, {"class": "dark-theme", "icon": "night", "name": "Dark Mode"}]'></dbp-theme-switcher> - </div> + <dbp-theme-switcher + themes='[{"class": "light-theme", "icon": "sun", "name": "Light Mode"}, {"class": "dark-theme", "icon": "night", "name": "Dark Mode"}]'></dbp-theme-switcher> + </div> </section> `; } - } commonUtils.defineCustomElement('dbp-theme-switcher-demo', ThemeSwitcherDemo); diff --git a/packages/theme-switcher/src/i18n.js b/packages/theme-switcher/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/theme-switcher/src/i18n.js +++ b/packages/theme-switcher/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/theme-switcher/src/i18n/de/translation.json b/packages/theme-switcher/src/i18n/de/translation.json index c25326d6c88fc436bcad450e2551a007bee3b8a9..b2adfe7363a1adf03f45213db205f600fb133370 100644 --- a/packages/theme-switcher/src/i18n/de/translation.json +++ b/packages/theme-switcher/src/i18n/de/translation.json @@ -1,5 +1,5 @@ { - "demo-title": "Theme Switcher Demo", - "intro": "Mit dem Theme-Switcher können Sie zwischen unterschiedlichen Farb-Themes umschalten.", - "color-mode": "Farbmodus ändern" + "demo-title": "Theme Switcher Demo", + "intro": "Mit dem Theme-Switcher können Sie zwischen unterschiedlichen Farb-Themes umschalten.", + "color-mode": "Farbmodus ändern" } diff --git a/packages/theme-switcher/src/i18n/en/translation.json b/packages/theme-switcher/src/i18n/en/translation.json index 5822689e39cd82942553e9f33921859b0adb1a8f..cd417f80d269dd775e461a0c184a2399be0e1a20 100644 --- a/packages/theme-switcher/src/i18n/en/translation.json +++ b/packages/theme-switcher/src/i18n/en/translation.json @@ -1,5 +1,5 @@ { - "demo-title": "Theme Switcher Demo", - "intro": "With the theme-switcher you can switch between multiple themes.", - "color-mode": "Farbmodus ändern" + "demo-title": "Theme Switcher Demo", + "intro": "With the theme-switcher you can switch between multiple themes.", + "color-mode": "Farbmodus ändern" } diff --git a/packages/theme-switcher/src/index.js b/packages/theme-switcher/src/index.js index 1b7dbe735cce4395a9df25651313183411c765b3..1ef8c2419e0a741c87d4695795fda16e18c2283f 100644 --- a/packages/theme-switcher/src/index.js +++ b/packages/theme-switcher/src/index.js @@ -1 +1 @@ -export {ThemeSwitcher} from './theme-switcher'; \ No newline at end of file +export {ThemeSwitcher} from './theme-switcher'; diff --git a/packages/theme-switcher/src/theme-switcher.js b/packages/theme-switcher/src/theme-switcher.js index 691cbc8ba08091419cf7d9308e2401af7c2deabf..0548c489028de08eabc43d99b8276782c2535b4e 100644 --- a/packages/theme-switcher/src/theme-switcher.js +++ b/packages/theme-switcher/src/theme-switcher.js @@ -5,7 +5,6 @@ import {AdapterLitElement, Icon} from '@dbp-toolkit/common'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {classMap} from 'lit/directives/class-map.js'; - export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { constructor() { super(); @@ -15,28 +14,27 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { this.themes = []; this.boundCloseAdditionalMenuHandler = this.hideModeMenu.bind(this); this.detectBrowserDarkMode = false; - this.darkModeClass = "dark-theme"; + this.darkModeClass = 'dark-theme'; } static get properties() { return { ...super.properties, - lang: { type: String }, - themes: { type: Array, attribute: "themes" }, - darkModeThemeOverride: {type: String, attribute: "dark-mode-theme-override"} + lang: {type: String}, + themes: {type: Array, attribute: 'themes'}, + darkModeThemeOverride: {type: String, attribute: 'dark-mode-theme-override'}, }; } static get scopedElements() { return { - 'dbp-icon': Icon + 'dbp-icon': Icon, }; } - update(changedProperties) { changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -46,18 +44,17 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { connectedCallback() { super.connectedCallback(); this.updateComplete.then(() => { - if (typeof this.darkModeThemeOverride === "undefined") { + if (typeof this.darkModeThemeOverride === 'undefined') { this.detectBrowserDarkMode = true; - } else if ( this.darkModeThemeOverride === "") { + } else if (this.darkModeThemeOverride === '') { this.detectBrowserDarkMode = false; } else { this.detectBrowserDarkMode = true; this.darkModeClass = this.darkModeThemeOverride; } - this.loadTheme("light-theme"); + this.loadTheme('light-theme'); this.detectInitialMode(); }); - } detectInitialMode() { @@ -65,7 +62,7 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { let prefMode = localStorage.getItem('prefered-color-mode'); if (prefMode) { // search for prefered mode - const theme = this.themes.find(theme => theme.class === prefMode); + const theme = this.themes.find((theme) => theme.class === prefMode); if (theme) { this.loadTheme(theme.class); @@ -75,10 +72,10 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { if (this.detectBrowserDarkMode) { //look for browser mode - const useDark = window.matchMedia("(prefers-color-scheme: dark)"); + const useDark = window.matchMedia('(prefers-color-scheme: dark)'); if (useDark.matches) { // search for dark mode - const theme = this.themes.find(theme => theme.class === this.darkModeClass); + const theme = this.themes.find((theme) => theme.class === this.darkModeClass); if (theme) { this.loadTheme(theme.class); @@ -88,27 +85,25 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { } toggleModeMenu() { - const button = this.shadowRoot.querySelector(".mode-button"); - if(!button) { + const button = this.shadowRoot.querySelector('.mode-button'); + if (!button) { return; } - if (button.classList.contains("active")) - button.classList.remove("active"); - else - button.classList.add("active"); - const menu = this.shadowRoot.querySelector("ul.extended-menu"); - const menuStart = this.shadowRoot.querySelector(".mode-button"); + if (button.classList.contains('active')) button.classList.remove('active'); + else button.classList.add('active'); + const menu = this.shadowRoot.querySelector('ul.extended-menu'); + const menuStart = this.shadowRoot.querySelector('.mode-button'); if (menu === null || menuStart === null) { return; } menu.classList.toggle('hidden'); - if (!menu.classList.contains('hidden')) { // add event listener for clicking outside of menu + if (!menu.classList.contains('hidden')) { + // add event listener for clicking outside of menu document.addEventListener('click', this.boundCloseAdditionalMenuHandler); this.initateOpenAdditionalMenu = true; - } - else { + } else { document.removeEventListener('click', this.boundCloseAdditionalMenuHandler); } } @@ -119,25 +114,24 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { return; } - const menu = this.shadowRoot.querySelector("ul.extended-menu"); - if (menu && !menu.classList.contains('hidden')) - this.toggleModeMenu(); + const menu = this.shadowRoot.querySelector('ul.extended-menu'); + if (menu && !menu.classList.contains('hidden')) this.toggleModeMenu(); } loadTheme(themeName) { - const button = this.shadowRoot.querySelector(".button-" + themeName); - const otherButtons = this.shadowRoot.querySelectorAll(".button-theme"); + const button = this.shadowRoot.querySelector('.button-' + themeName); + const otherButtons = this.shadowRoot.querySelectorAll('.button-theme'); const body = this.shadowRoot.host.getRootNode({composed: true}).body; - if (button === null || otherButtons.length === 0 || body === null ) { + if (button === null || otherButtons.length === 0 || body === null) { return; } - otherButtons.forEach(button => button.classList.remove("active")); - button.classList.add("active"); + otherButtons.forEach((button) => button.classList.remove('active')); + button.classList.add('active'); if (!body.classList.contains(themeName)) { - this.themes.forEach(theme => { + this.themes.forEach((theme) => { body.classList.remove(theme.class); }); @@ -147,10 +141,10 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { saveTheme(themeName) { //set active state - const browserModeDark = window.matchMedia("(prefers-color-scheme: dark)"); - const browserModeLight = window.matchMedia("(prefers-color-scheme: light)"); + const browserModeDark = window.matchMedia('(prefers-color-scheme: dark)'); + const browserModeLight = window.matchMedia('(prefers-color-scheme: light)'); - if (themeName === "light-theme" && browserModeLight.matches) { + if (themeName === 'light-theme' && browserModeLight.matches) { localStorage.removeItem('prefered-color-mode'); } else if (themeName === this.darkModeClass && browserModeDark.matches) { localStorage.removeItem('prefered-color-mode'); @@ -169,61 +163,61 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { mode-button, button.button { border: none; } - - .active, .extended-menu li a.active dbp-icon { + + .active, + .extended-menu li a.active dbp-icon { color: var(--dbp-accent); } - + .active { font-weight: bolder; } - - a:hover:not(.active) , .extended-menu li a:hover:not(.active) { - color: var(--dbp-hover-text); - background-color: var(--dbp-hover-base); - transition: none; + + a:hover:not(.active), + .extended-menu li a:hover:not(.active) { + color: var(--dbp-hover-text); + background-color: var(--dbp-hover-base); + transition: none; } - + a { - padding: 0.3em; - display: inline-block; - text-decoration: none; - transition: background-color 0.15s, color 0.15s; - color: var(--dbp-text); + padding: 0.3em; + display: inline-block; + text-decoration: none; + transition: background-color 0.15s, color 0.15s; + color: var(--dbp-text); } - + .extended-menu { - list-style: none; - border: var(--dbp-border); - position: absolute; - background-color: var(--dbp-base); - z-index: 1000; - border-radius: var(--dbp-border-radius); + list-style: none; + border: var(--dbp-border); + position: absolute; + background-color: var(--dbp-base); + z-index: 1000; + border-radius: var(--dbp-border-radius); } - + .extended-menu li { - - text-align: left; - min-width: 160px; + text-align: left; + min-width: 160px; } - + .extended-menu li a { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - padding: 12px 15px; - w1idth: 100%; - box-sizing: border-box; - text-align: left; - color: var(--dbp-text); - background: none; - display: block + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding: 12px 15px; + w1idth: 100%; + box-sizing: border-box; + text-align: left; + color: var(--dbp-text); + background: none; + display: block; } - + .icon { margin-right: 10px; } - `; } @@ -232,18 +226,33 @@ export class ThemeSwitcher extends ScopedElementsMixin(AdapterLitElement) { return html` <div class="${classMap({hidden: this.themes.length <= 1})}"> - <a class="mode-button" title="${i18n.t('color-mode')}" - @click="${() => {this.toggleModeMenu();}}"><dbp-icon name="contrast"></dbp-icon></a> - <ul class='extended-menu hidden'> - ${this.themes.map(theme => html` - <li class="" id="${theme.class}"> - <a class="button-theme button-${theme.class}" @click="${() => {this.loadTheme(theme.class); this.saveTheme(theme.class);}}" title="${theme.name}"> - <dbp-icon class="icon" name="${theme.icon}"></dbp-icon> ${theme.name} - </a> - </li> - `)} + <a + class="mode-button" + title="${i18n.t('color-mode')}" + @click="${() => { + this.toggleModeMenu(); + }}"> + <dbp-icon name="contrast"></dbp-icon> + </a> + <ul class="extended-menu hidden"> + ${this.themes.map( + (theme) => html` + <li class="" id="${theme.class}"> + <a + class="button-theme button-${theme.class}" + @click="${() => { + this.loadTheme(theme.class); + this.saveTheme(theme.class); + }}" + title="${theme.name}"> + <dbp-icon class="icon" name="${theme.icon}"></dbp-icon> + ${theme.name} + </a> + </li> + ` + )} </ul> </div> `; } -} \ No newline at end of file +} diff --git a/packages/theme-switcher/test/unit.js b/packages/theme-switcher/test/unit.js index d235d545b1b3c652021b24f6493b752ff40cef0b..ddd1292a84c2fc117a1928bd2ff41e0d80b43535 100644 --- a/packages/theme-switcher/test/unit.js +++ b/packages/theme-switcher/test/unit.js @@ -4,37 +4,37 @@ import '../src/dbp-theme-switcher'; import '../src/demo'; suite('dbp-theme-switcher basics', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-theme-switcher'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-theme-switcher'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); suite('dbp-theme-switcher demo', () => { - let node; + let node; - setup(async () => { - node = document.createElement('dbp-theme-switcher-demo'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-theme-switcher-demo'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); }); diff --git a/packages/tooltip/.eslintrc.json b/packages/tooltip/.eslintrc.json index d72b93bea3b7ce923648f9b14a916bb02dd2b348..fa3ff177933ba9b421ff80decf79b7d35ac03c0f 100644 --- a/packages/tooltip/.eslintrc.json +++ b/packages/tooltip/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../../eslint.common.json" -} \ No newline at end of file +} diff --git a/packages/tooltip/.prettierignore b/packages/tooltip/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/tooltip/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/tooltip/.prettierrc.json b/packages/tooltip/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/tooltip/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/tooltip/i18next-scanner.config.js b/packages/tooltip/i18next-scanner.config.js index aeb8fdb6532e6c951401ba91424e2a256353d391..f0f86ce027f31d591de02dee8cd05089203735b5 100644 --- a/packages/tooltip/i18next-scanner.config.js +++ b/packages/tooltip/i18next-scanner.config.js @@ -1,16 +1,14 @@ module.exports = { - input: [ - 'src/*.js', - ], + input: ['src/*.js'], output: './', options: { debug: false, removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, - lngs: ['en','de'], + lngs: ['en', 'de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', - savePath: 'src/i18n/{{lng}}/{{ns}}.json' + savePath: 'src/i18n/{{lng}}/{{ns}}.json', }, }, -} +}; diff --git a/packages/tooltip/package.json b/packages/tooltip/package.json index 4a5a8b87a929b61660a69ff18f6b2db9eec3446d..b292511d24b2d1e4e927a91791b0e683ff02ee28 100644 --- a/packages/tooltip/package.json +++ b/packages/tooltip/package.json @@ -1,59 +1,63 @@ { - "name": "@dbp-toolkit/tooltip", - "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/tooltip", - "version": "0.0.1", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/tooltip" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-replace": "^2.2.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" - }, - "dependencies": { - "@dbp-toolkit/auth": "^0.2.2", - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "lit": "^2.0.0", - "tippy.js": "^6.3.1" - }, - "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": "rollup -c --watch", - "watch-local": "yarn run watch", - "watch-dev": "rollup -c --watch --environment BUILD:development", - "test": "rollup -c --environment BUILD:test && karma start --singleRun", - "lint": "eslint ." - } + "name": "@dbp-toolkit/tooltip", + "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/tooltip", + "version": "0.0.1", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/tooltip" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-replace": "^2.2.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2" + }, + "dependencies": { + "@dbp-toolkit/auth": "^0.2.2", + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "lit": "^2.0.0", + "tippy.js": "^6.3.1" + }, + "scripts": { + "clean": "rm dist/*", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "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": "rollup -c --watch", + "watch-local": "yarn run watch", + "watch-dev": "rollup -c --watch --environment BUILD:development", + "test": "rollup -c --environment BUILD:test && karma start --singleRun", + "lint": "eslint ." + } } diff --git a/packages/tooltip/rollup.config.js b/packages/tooltip/rollup.config.js index b0d23052d642532524af9a4c112e3370f31fb418..c99ae9b7501c28ce9eb91bb62ad5972186f3b247 100644 --- a/packages/tooltip/rollup.config.js +++ b/packages/tooltip/rollup.config.js @@ -2,18 +2,18 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import url from "@rollup/plugin-url"; +import url from '@rollup/plugin-url'; import del from 'rollup-plugin-delete'; -import emitEJS from 'rollup-plugin-emit-ejs' +import emitEJS from 'rollup-plugin-emit-ejs'; import {getPackagePath, getDistPath} from '../../rollup.utils.js'; import replace from 'rollup-plugin-replace'; const pkg = require('./package.json'); -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); function getBuildInfo() { const child_process = require('child_process'); @@ -25,7 +25,7 @@ function getBuildInfo() { let parsed = url.parse(remote); // convert git urls if (parsed.protocol === null) { - parsed = url.parse('git://' + remote.replace(":", "/")); + parsed = url.parse('git://' + remote.replace(':', '/')); parsed.protocol = 'https:'; } let newPath = parsed.path.slice(0, parsed.path.lastIndexOf('.')); @@ -35,23 +35,26 @@ function getBuildInfo() { info: commit, url: newUrl, time: new Date().toISOString(), - env: build - } + env: build, + }; } export default (async () => { return { - input: (build != 'test') ? ['src/dbp-tooltip.js', 'src/dbp-tooltip-demo.js'] : glob.sync('test/**/*.js'), + input: + build != 'test' + ? ['src/dbp-tooltip.js', 'src/dbp-tooltip-demo.js'] + : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), emitEJS({ src: 'assets', @@ -65,8 +68,8 @@ export default (async () => { }, name: pkg.name, environment: build, - buildInfo: getBuildInfo() - } + buildInfo: getBuildInfo(), + }, }), resolve(), commonjs(), @@ -77,21 +80,26 @@ export default (async () => { await getPackagePath('tippy.js', '**/*.css'), ], emitFiles: true, - fileName: 'shared/[name].[hash][extname]' + fileName: 'shared/[name].[hash][extname]', }), json(), - (build !== 'local' && build !== 'test') ? terser() : false, + build !== 'local' && build !== 'test' ? terser() : false, copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, - {src: 'assets/favicon.ico', dest:'dist'}, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, + {src: 'assets/favicon.ico', dest: 'dist'}, ], }), replace({ - 'process.env.NODE_ENV': JSON.stringify('production') + 'process.env.NODE_ENV': JSON.stringify('production'), }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; })(); diff --git a/packages/tooltip/src/button-tooltip.js b/packages/tooltip/src/button-tooltip.js index 53b3d2b0b7dc9df56a8c924b350b367355a03439..14836f8088d4392f980a2c53a6bbf50291dfcb00 100644 --- a/packages/tooltip/src/button-tooltip.js +++ b/packages/tooltip/src/button-tooltip.js @@ -7,7 +7,6 @@ import tippy from 'tippy.js'; import tippy2CSSPath from 'tippy.js/dist/tippy.css'; export class ButtonTooltip extends ScopedElementsMixin(DBPLitElement) { - constructor() { super(); this.textContent = 'missing text.'; @@ -20,10 +19,10 @@ export class ButtonTooltip extends ScopedElementsMixin(DBPLitElement) { static get properties() { return { ...super.properties, - textContent: { type: String, attribute: 'text-content' }, - buttonText: { type: String, attribute: 'button-text' }, - type: { type: String }, - formId: { type: String, attribute: 'form-id' }, + textContent: {type: String, attribute: 'text-content'}, + buttonText: {type: String, attribute: 'button-text'}, + type: {type: String}, + formId: {type: String, attribute: 'form-id'}, }; } @@ -76,31 +75,34 @@ export class ButtonTooltip extends ScopedElementsMixin(DBPLitElement) { top: 2px; position: relative; } - `; } render() { - const tippy2CSS = commonUtils.getAssetURL(tippy2CSSPath); - + this.setOrUpdateTippy(); return html` - <link rel="stylesheet" href="${tippy2CSS}"> + <link rel="stylesheet" href="${tippy2CSS}" /> <button id="info-tooltip-button"> <div class="info-icon"> <!-- https://icons.getbootstrap.com/icons/info-circle/ --> - <svg - xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> - <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> - <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> + <svg + xmlns="http://www.w3.org/2000/svg" + width="16" + height="16" + fill="currentColor" + class="bi bi-info-circle" + viewBox="0 0 16 16"> + <path + d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" /> + <path + d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" /> </svg> </div> ${this.buttonText} </button> - `; } - } diff --git a/packages/tooltip/src/dbp-tooltip-demo.js b/packages/tooltip/src/dbp-tooltip-demo.js index 595b50f7f08b27fde06eb1131b9d5b00300fa55e..59d4025cc6df585e46268f48e23ad85542ac8c0f 100644 --- a/packages/tooltip/src/dbp-tooltip-demo.js +++ b/packages/tooltip/src/dbp-tooltip-demo.js @@ -6,11 +6,9 @@ import * as commonStyles from '@dbp-toolkit/common/styles'; import {TooltipElement} from './tooltip'; import {InfoTooltip} from './info-tooltip'; import {ButtonTooltip} from './button-tooltip'; -import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; - +import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; export class TooltipDemo extends ScopedElementsMixin(DBPLitElement) { - constructor() { super(); this._i18n = createInstance(); @@ -28,13 +26,13 @@ export class TooltipDemo extends ScopedElementsMixin(DBPLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, + lang: {type: String}, }; } update(changedProperties) { - changedProperties.forEach((oldValue, propName) => { - if (propName === "lang") { + changedProperties.forEach((oldValue, propName) => { + if (propName === 'lang') { this._i18n.changeLanguage(this.lang); } }); @@ -48,15 +46,23 @@ export class TooltipDemo extends ScopedElementsMixin(DBPLitElement) { commonStyles.getThemeCSS(), commonStyles.getGeneralCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em; padding-left:20px;} - .group { display: flex; flex-direction: auto; column-gap: 3px; } - ` + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + padding-left: 20px; + } + .group { + display: flex; + flex-direction: auto; + column-gap: 3px; + } + `, ]; } render() { - return html` <section class="section"> <div class="container"> @@ -64,20 +70,27 @@ export class TooltipDemo extends ScopedElementsMixin(DBPLitElement) { </div> <div class="container"> <h2>Standard Info Tooltip</h2> - <p>Mind the gap! - <dbp-info-tooltip text-content="tippy info tooltip demo text" interactive></dbp-info-tooltip> + <p> + Mind the gap! + <dbp-info-tooltip + text-content="tippy info tooltip demo text" + interactive></dbp-info-tooltip> </p> </div> <div class="container"> <h2>Custom Tooltip</h2> <p>Choose an icon from those bundled with your app.</p> - <p>Mind the gap! - <dbp-tooltip text-content="tippy tooltip demo text" icon-name="information"></dbp-tooltip> + <p> + Mind the gap! + <dbp-tooltip + text-content="tippy tooltip demo text" + icon-name="information"></dbp-tooltip> </p> </div> <div class="container"> <h2>Incorrectly Configured Tooltip</h2> - <p>Missing text, default icon: + <p> + Missing text, default icon: <dbp-tooltip></dbp-tooltip> </p> </div> @@ -86,10 +99,24 @@ export class TooltipDemo extends ScopedElementsMixin(DBPLitElement) { <p>Add a tooltip info to your submit/reset button.</p> <form action="/" class="group"> <label for="text">Text</label> - <input type="text" id="text" name="text" value="" placeholder="text"> - <div><dbp-button-tooltip button-text="save" text-content="submit to server"></dbp-button-tooltip></div> - <div><dbp-button-tooltip button-text="reset" text-content="clear all inputs" type="reset"></dbp-button-tooltip></div> - <div><dbp-button-tooltip button-text="silent" text-content="does nothing" type="btn"></dbp-button-tooltip></div> + <input type="text" id="text" name="text" value="" placeholder="text" /> + <div> + <dbp-button-tooltip + button-text="save" + text-content="submit to server"></dbp-button-tooltip> + </div> + <div> + <dbp-button-tooltip + button-text="reset" + text-content="clear all inputs" + type="reset"></dbp-button-tooltip> + </div> + <div> + <dbp-button-tooltip + button-text="silent" + text-content="does nothing" + type="btn"></dbp-button-tooltip> + </div> </form> </div> </section> diff --git a/packages/tooltip/src/i18n.js b/packages/tooltip/src/i18n.js index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/tooltip/src/i18n.js +++ b/packages/tooltip/src/i18n.js @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/tooltip/src/index.js b/packages/tooltip/src/index.js index 9ff26091c2f873e6b3e23c74e1eed4303363522d..0081f6a682679d96f76b8c0960d20746d88f8b1b 100644 --- a/packages/tooltip/src/index.js +++ b/packages/tooltip/src/index.js @@ -2,4 +2,4 @@ import {InfoTooltip} from './info-tooltip.js'; import {TooltipElement} from './tooltip.js'; export {InfoTooltip as InfoTooltip}; -export {TooltipElement as TooltipElement}; \ No newline at end of file +export {TooltipElement as TooltipElement}; diff --git a/packages/tooltip/src/info-tooltip.js b/packages/tooltip/src/info-tooltip.js index 868fbcec31de292076f3234683d88331ba27678b..82684a488aa72cc23591ba6d2b2c0b8f9c0bec8b 100644 --- a/packages/tooltip/src/info-tooltip.js +++ b/packages/tooltip/src/info-tooltip.js @@ -8,7 +8,6 @@ import tippy2CSSPath from 'tippy.js/dist/tippy.css'; import {Icon} from '@dbp-toolkit/common'; export class InfoTooltip extends ScopedElementsMixin(DBPLitElement) { - constructor() { super(); this.textContent = 'missing text.'; @@ -24,8 +23,8 @@ export class InfoTooltip extends ScopedElementsMixin(DBPLitElement) { static get properties() { return { ...super.properties, - textContent: { type: String, attribute: 'text-content' }, - interactive: { type: Boolean, attribute: true }, + textContent: {type: String, attribute: 'text-content'}, + interactive: {type: Boolean, attribute: true}, }; } @@ -79,24 +78,22 @@ export class InfoTooltip extends ScopedElementsMixin(DBPLitElement) { color: var(--dbp-text-inverted); } - .tippy-arrow{ - color: var(--dbp-text); + .tippy-arrow { + color: var(--dbp-text); } `; } render() { - const tippy2CSS = commonUtils.getAssetURL(tippy2CSSPath); - + this.setOrUpdateTippy(); return html` - <link rel="stylesheet" href="${tippy2CSS}"> + <link rel="stylesheet" href="${tippy2CSS}" /> <div class="info-icon" id="info-tooltip-icon"> <dbp-icon name="information-circle"></dbp-icon> </div> `; } - } diff --git a/packages/tooltip/src/tooltip.js b/packages/tooltip/src/tooltip.js index e4efd8b8a78c2ec76bbae5c6ba7e38bdacac06a5..6b34ba678a8226bc3fb614b7c4ee8d071f980696 100644 --- a/packages/tooltip/src/tooltip.js +++ b/packages/tooltip/src/tooltip.js @@ -8,7 +8,6 @@ import {Icon} from '@dbp-toolkit/common'; import tippy2CSSPath from 'tippy.js/dist/tippy.css'; export class TooltipElement extends ScopedElementsMixin(DBPLitElement) { - constructor() { super(); this.textContent = 'missing text.'; @@ -24,8 +23,8 @@ export class TooltipElement extends ScopedElementsMixin(DBPLitElement) { static get properties() { return { ...super.properties, - textContent: { type: String, attribute: 'text-content' }, - iconName: { type: String, attribute: 'icon-name' }, + textContent: {type: String, attribute: 'text-content'}, + iconName: {type: String, attribute: 'icon-name'}, }; } @@ -60,39 +59,50 @@ export class TooltipElement extends ScopedElementsMixin(DBPLitElement) { display: inline; color: var(--dbp-text); } - `; } render() { - const tippy2CSS = commonUtils.getAssetURL(tippy2CSSPath); - + this.setOrUpdateTippy(); return html` - <link rel="stylesheet" href="${tippy2CSS}"> + <link rel="stylesheet" href="${tippy2CSS}" /> <div class="tooltip-icon"> - ${ this.iconName ? - html`<dbp-icon name="${this.iconName}" id="tooltip-icon"></dbp-icon>` - - : html`<!-- https://www.svgrepo.com/svg/89416/skull --> -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" - id="tooltip-icon" x="0" y="0" viewBox="0 0 360 360" xml:space="preserve"> - <g> - <path d="M180,0C97.157,0,30,67.157,30,150v109.667h0.016c0.337,13.559,7.045,22.475,19.879,26.753L105,305v30 + ${this.iconName + ? html` + <dbp-icon name="${this.iconName}" id="tooltip-icon"></dbp-icon> + ` + : html` + <!-- https://www.svgrepo.com/svg/89416/skull --> + <svg + xmlns="http://www.w3.org/2000/svg" + width="16" + height="16" + fill="currentColor" + id="tooltip-icon" + x="0" + y="0" + viewBox="0 0 360 360" + xml:space="preserve"> + <g> + <path + d="M180,0C97.157,0,30,67.157,30,150v109.667h0.016c0.337,13.559,7.045,22.475,19.879,26.753L105,305v30 c0,13.75,11.25,25,25,25h100c13.75,0,25-11.25,25-25v-30l55.051-18.668c12.834-4.278,19.597-13.106,19.934-26.665H330V150 C330,67.157,262.843,0,180,0z M300,258.063l-54.635,18.526L225,283.495V305v25h-90v-25v-21.544l-20.415-6.884L60,258.168V150 c0-32.053,12.482-62.188,35.147-84.853C117.813,42.482,147.947,30,180,30s62.188,12.482,84.853,35.147 -C287.518,87.813,300,117.947,300,150V258.063z"/> - <path d="M160,281c0,11.046,8.954,20,20,20s20-8.954,20-20s-20-40-20-40S160,269.954,160,281z"/> - <path d="M125,161c-24.854,0-45,20.146-45,45s20.146,45,45,45s45-20.146,45-45S149.854,161,125,161z M125,221c-8.271,0-15-6.729-15-15s6.729-15,15-15s15,6.729,15,15S133.271,221,125,221z"/> - <path d="M190,206c0,24.854,20.146,45,45,45s45-20.146,45-45s-20.147-45-45-45S190,181.146,190,206z M250,206c0,8.271-6.729,15-15,15s-15-6.729-15-15s6.729-15,15-15S250,197.729,250,206z"/> - </g> -</svg>` } +C287.518,87.813,300,117.947,300,150V258.063z" /> + <path + d="M160,281c0,11.046,8.954,20,20,20s20-8.954,20-20s-20-40-20-40S160,269.954,160,281z" /> + <path + d="M125,161c-24.854,0-45,20.146-45,45s20.146,45,45,45s45-20.146,45-45S149.854,161,125,161z M125,221c-8.271,0-15-6.729-15-15s6.729-15,15-15s15,6.729,15,15S133.271,221,125,221z" /> + <path + d="M190,206c0,24.854,20.146,45,45,45s45-20.146,45-45s-20.147-45-45-45S190,181.146,190,206z M250,206c0,8.271-6.729,15-15,15s-15-6.729-15-15s6.729-15,15-15S250,197.729,250,206z" /> + </g> + </svg> + `} </div> - `; } - } diff --git a/packages/tooltip/test/unit.js b/packages/tooltip/test/unit.js index 007cddaac9d48ccb68aa0230433cc3e46af9ae57..b5306f35fc092316cc768abdb9dd892b79fa2922 100644 --- a/packages/tooltip/test/unit.js +++ b/packages/tooltip/test/unit.js @@ -3,19 +3,18 @@ import '../src/dbp-tooltip'; suite('dbp-tooltip', () => { let node; - + setup(async () => { - node = document.createElement('dbp-tooltip'); - document.body.appendChild(node); - await node.updateComplete; + node = document.createElement('dbp-tooltip'); + document.body.appendChild(node); + await node.updateComplete; }); - + teardown(() => { - node.remove(); + node.remove(); }); - + test('should render', () => { - assert.isNotNull(node.shadowRoot); + assert.isNotNull(node.shadowRoot); }); - }); - +}); diff --git a/packages/typescript-example/.eslintrc.json b/packages/typescript-example/.eslintrc.json index f6dc00c7f307b65ba2fc83be98ba6f79cadbf1e5..35eb3ac41d1e60af269e8a5cf368ba97fc83f082 100644 --- a/packages/typescript-example/.eslintrc.json +++ b/packages/typescript-example/.eslintrc.json @@ -9,11 +9,7 @@ "parserOptions": { "ecmaVersion": 2020, "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "eslint:recommended" - ] -} \ No newline at end of file + }, + "plugins": ["@typescript-eslint"], + "extends": ["eslint:recommended"] +} diff --git a/packages/typescript-example/.prettierignore b/packages/typescript-example/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..68e724f6c0751675600c23ca3c70dd28bac7ce2a --- /dev/null +++ b/packages/typescript-example/.prettierignore @@ -0,0 +1,3 @@ +node_modules/ +/dist +/vendor diff --git a/packages/typescript-example/.prettierrc.json b/packages/typescript-example/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/packages/typescript-example/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/packages/typescript-example/package.json b/packages/typescript-example/package.json index 6a47609210e28f31279f8c67ffe45e25331a4005..9bdb39ec60880afe11e3c708cdc6d3a1e6594888 100644 --- a/packages/typescript-example/package.json +++ b/packages/typescript-example/package.json @@ -1,51 +1,55 @@ { - "name": "@dbp-toolkit/typescript-example", - "version": "0.2.3", - "main": "src/index.js", - "license": "LGPL-2.1-or-later", - "repository": { - "type": "git", - "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", - "directory": "packages/typescript-example" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org", - "access": "public" - }, - "devDependencies": { - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@types/mocha": "^9.0.0", - "eslint": "^8.0.0", - "@typescript-eslint/eslint-plugin": "^5.0.0-alpha.42", - "@typescript-eslint/parser": "^5.0.0-alpha.42", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.0.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.33.3", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-typescript2": "^0.31.0", - "ts-lit-plugin": "^1.2.1", - "tslib": "^2.0.3", - "typescript": "^4.1.2" - }, - "dependencies": { - "@dbp-toolkit/common": "^0.2.2", - "@open-wc/scoped-elements": "^2.0.0", - "lit": "^2.0.0" - }, - "scripts": { - "clean": "rm dist/*", - "build": "rollup -c", - "watch": "rollup -c --watch", - "test": "rollup -c --environment BUILD:test && karma start --singleRun", - "lint": "eslint . --ext .js,.ts" - } + "name": "@dbp-toolkit/typescript-example", + "version": "0.2.3", + "main": "src/index.js", + "license": "LGPL-2.1-or-later", + "repository": { + "type": "git", + "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git", + "directory": "packages/typescript-example" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org", + "access": "public" + }, + "devDependencies": { + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@types/mocha": "^9.0.0", + "@typescript-eslint/eslint-plugin": "^5.0.0-alpha.42", + "@typescript-eslint/parser": "^5.0.0-alpha.42", + "eslint": "^8.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.0.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.33.3", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2", + "rollup-plugin-typescript2": "^0.31.0", + "ts-lit-plugin": "^1.2.1", + "tslib": "^2.0.3", + "typescript": "^4.1.2" + }, + "dependencies": { + "@dbp-toolkit/common": "^0.2.2", + "@open-wc/scoped-elements": "^2.0.0", + "lit": "^2.0.0" + }, + "scripts": { + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "clean": "rm dist/*", + "build": "rollup -c", + "watch": "rollup -c --watch", + "test": "rollup -c --environment BUILD:test && karma start --singleRun", + "lint": "eslint . --ext .js,.ts" + } } diff --git a/packages/typescript-example/rollup.config.js b/packages/typescript-example/rollup.config.js index 9b2a0b1396ccdeede3ab399030407e87a242ff99..cd91cd9d2cf993dc5877571128fffa12f252ab7b 100644 --- a/packages/typescript-example/rollup.config.js +++ b/packages/typescript-example/rollup.config.js @@ -2,38 +2,41 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; import del from 'rollup-plugin-delete'; import typescript from 'rollup-plugin-typescript2'; -const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; -console.log("build: " + build); +const build = typeof process.env.BUILD !== 'undefined' ? process.env.BUILD : 'local'; +console.log('build: ' + build); export default { - input: (build != 'test') ? ['src/dbp-typescript-example.ts', 'src/dbp-typescript-example-demo.ts'] : glob.sync('test/**/*.ts'), + input: + build != 'test' + ? ['src/dbp-typescript-example.ts', 'src/dbp-typescript-example-demo.ts'] + : glob.sync('test/**/*.ts'), output: { dir: 'dist', entryFileNames: '[name].js', chunkFileNames: 'shared/[name].[hash].[format].js', format: 'esm', - sourcemap: true + sourcemap: true, }, plugins: [ del({ - targets: 'dist/*' + targets: 'dist/*', }), resolve(), commonjs(), json(), typescript(), - (build !== 'local' && build !== 'test') ? terser() : terser(), + build !== 'local' && build !== 'test' ? terser() : terser(), copy({ - targets: [ - {src: 'assets/index.html', dest: 'dist'}, - ], + targets: [{src: 'assets/index.html', dest: 'dist'}], }), - (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false - ] + process.env.ROLLUP_WATCH === 'true' + ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) + : false, + ], }; diff --git a/packages/typescript-example/src/dbp-typescript-example-demo.ts b/packages/typescript-example/src/dbp-typescript-example-demo.ts index 24c96a7326df713eb87ba813a816c8f7bc5bac0b..a56b922c640710696ef1871e03114bbb63ae5a87 100644 --- a/packages/typescript-example/src/dbp-typescript-example-demo.ts +++ b/packages/typescript-example/src/dbp-typescript-example-demo.ts @@ -1,13 +1,12 @@ import {html, LitElement, TemplateResult} from 'lit'; import {TypeScriptExample} from './typescript-example'; import * as commonUtils from '@dbp-toolkit/common/utils'; -import { ScopedElementsMixin, ScopedElementsMap } from '@open-wc/scoped-elements'; +import {ScopedElementsMixin, ScopedElementsMap} from '@open-wc/scoped-elements'; export class TypeScriptExampleDemo extends ScopedElementsMixin(LitElement) { - static get scopedElements(): ScopedElementsMap { return { - 'dbp-typescript-example': TypeScriptExample, + 'dbp-typescript-example': TypeScriptExample, }; } diff --git a/packages/typescript-example/src/i18n.ts b/packages/typescript-example/src/i18n.ts index 975c1993e2a567940c74f8d957a6b2a018125548..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/typescript-example/src/i18n.ts +++ b/packages/typescript-example/src/i18n.ts @@ -5,4 +5,4 @@ import en from './i18n/en/translation.json'; export function createInstance() { return _createInstance({en: en, de: de}, 'de', 'en'); -} \ No newline at end of file +} diff --git a/packages/typescript-example/src/i18n/de/translation.json b/packages/typescript-example/src/i18n/de/translation.json index dcf5d832a1e6010fdbcbda76b507d5ee91396ab2..9a110e0eb1ea9adfe4fca9b98ec578044d83b922 100644 --- a/packages/typescript-example/src/i18n/de/translation.json +++ b/packages/typescript-example/src/i18n/de/translation.json @@ -1,3 +1,3 @@ { - "hello-world": "Hallo Welt" + "hello-world": "Hallo Welt" } diff --git a/packages/typescript-example/src/i18n/en/translation.json b/packages/typescript-example/src/i18n/en/translation.json index 29468fe3108dfb1acd2c7bf2953e150e0b02b40c..3b4330013534d7661c1be467f0afcb0434209a6a 100644 --- a/packages/typescript-example/src/i18n/en/translation.json +++ b/packages/typescript-example/src/i18n/en/translation.json @@ -1,4 +1,3 @@ { "hello-world": "Hello World" - } - \ No newline at end of file +} diff --git a/packages/typescript-example/src/index.ts b/packages/typescript-example/src/index.ts index dbcc5d08855225a2103a96b7577e266d84313012..00323299cb668202a3f81ffd8675cf8ef3806847 100644 --- a/packages/typescript-example/src/index.ts +++ b/packages/typescript-example/src/index.ts @@ -1 +1 @@ -// no content \ No newline at end of file +// no content diff --git a/packages/typescript-example/src/typescript-example.ts b/packages/typescript-example/src/typescript-example.ts index ed22bd66bc463321f2e04f1386c960251c7c5897..3df50f6763e8e2dfb223ab7ce98a2195d714a6d8 100644 --- a/packages/typescript-example/src/typescript-example.ts +++ b/packages/typescript-example/src/typescript-example.ts @@ -1,8 +1,7 @@ -import {html,LitElement} from 'lit'; +import {html, LitElement} from 'lit'; import {createInstance} from './i18n'; export class TypeScriptExample extends LitElement { - private _i18n; constructor() { @@ -14,12 +13,12 @@ export class TypeScriptExample extends LitElement { static get properties() { return { - lang: {type: String} + lang: {type: String}, }; } update(changedProperties) { - if (changedProperties.has("lang")) { + if (changedProperties.has('lang')) { this._i18n.changeLanguage(this.lang); } super.update(changedProperties); @@ -30,4 +29,4 @@ export class TypeScriptExample extends LitElement { <h3>${this._i18n.t('hello-world')}</h3> `; } -} \ No newline at end of file +} diff --git a/packages/typescript-example/test/unit.ts b/packages/typescript-example/test/unit.ts index b8aa33284335d74152d0af30431a28d7a6e08de3..5e61a70b30c6057ddc9f79d0c139f79573bb71b1 100644 --- a/packages/typescript-example/test/unit.ts +++ b/packages/typescript-example/test/unit.ts @@ -3,19 +3,19 @@ import {assert} from '@esm-bundle/chai'; import '../src/dbp-typescript-example'; suite('dbp-language-select basics', () => { - let node + let node; - setup(async () => { - node = document.createElement('dbp-typescript-example'); - document.body.appendChild(node); - await node.updateComplete; - }); + setup(async () => { + node = document.createElement('dbp-typescript-example'); + document.body.appendChild(node); + await node.updateComplete; + }); - teardown(() => { - node.remove(); - }); + teardown(() => { + node.remove(); + }); - test('should render', () => { - assert.isNotNull(node.shadowRoot); - }); -}); \ No newline at end of file + test('should render', () => { + assert.isNotNull(node.shadowRoot); + }); +}); diff --git a/packages/typescript-example/tsconfig.json b/packages/typescript-example/tsconfig.json index d33cea24ce38f4d54a45e14f302896bdd235c8be..a18cf6f568ec955260e6e7f6e797f36a71ec415f 100644 --- a/packages/typescript-example/tsconfig.json +++ b/packages/typescript-example/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "target": "ESNext", - "module": "ESNext", - "lib": ["ESNext", "dom", "dom.iterable"], - "sourceMap": true, - "outDir": "./dist", - "rootDir": "./", - "moduleResolution": "node", - "experimentalDecorators": true, - "allowSyntheticDefaultImports": true, - "resolveJsonModule": true, - "plugins": [ - { - "name": "ts-lit-plugin", - "strict": true - } - ] - }, - "include": ["src/**/*.ts", "test/**/*.ts"], - "exclude": [] -} \ No newline at end of file + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "lib": ["ESNext", "dom", "dom.iterable"], + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./", + "moduleResolution": "node", + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "plugins": [ + { + "name": "ts-lit-plugin", + "strict": true + } + ] + }, + "include": ["src/**/*.ts", "test/**/*.ts"], + "exclude": [] +} diff --git a/toolkit-showcase/.eslintrc.json b/toolkit-showcase/.eslintrc.json index 0d21e0638f87dcb951b857fd55b8f9154ed407e6..d19bc82f58a056a62e7f4f93eb8e319b1f357c44 100644 --- a/toolkit-showcase/.eslintrc.json +++ b/toolkit-showcase/.eslintrc.json @@ -1,4 +1,4 @@ { "root": true, "extends": "./../eslint.common.json" -} \ No newline at end of file +} diff --git a/toolkit-showcase/.prettierignore b/toolkit-showcase/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..a78d528cbd719d28d4e28042b72d5af625b5666e --- /dev/null +++ b/toolkit-showcase/.prettierignore @@ -0,0 +1,2 @@ +node_modules/ +/dist diff --git a/toolkit-showcase/.prettierrc.json b/toolkit-showcase/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..fecd75dc82be60e441465a1b88059c64b8622d71 --- /dev/null +++ b/toolkit-showcase/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "bracketSpacing": false, + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "bracketSameLine": true, + "htmlWhitespaceSensitivity": "ignore", + "overrides": [ + { + "files": "*.js", + "options": { + "semi": true + } + } + ] +} diff --git a/toolkit-showcase/app.config.js b/toolkit-showcase/app.config.js index 83894a0b3cbe54dd3a6fefc8e3096c891a0bb5ba..49f366697994d08daad36c8f63e224f74e0a2468 100644 --- a/toolkit-showcase/app.config.js +++ b/toolkit-showcase/app.config.js @@ -32,4 +32,4 @@ export default { nextcloudBaseURL: 'https://cloud-demo.tugraz.at', nextcloudName: 'TU Graz cloud', }, -}; \ No newline at end of file +}; diff --git a/toolkit-showcase/assets/auth.metadata.json b/toolkit-showcase/assets/auth.metadata.json index 43eecda43c606666abbcde010da655c8f983982b..aa7561ee57aa6f094be79bfb8bd72d3b89e9e8a5 100644 --- a/toolkit-showcase/assets/auth.metadata.json +++ b/toolkit-showcase/assets/auth.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-auth-demo-activity", - "module_src": "dbp-auth-demo-activity.js", - "routing_name": "auth", - "name": { - "de": "Authentifikation Komponente", - "en": "Authentication component" - }, - "short_name": { - "de": "Auth Komponente", - "en": "Auth component" - }, - "description": { - "de": "Web Komponente zur Authentifikation", - "en": "Auth web component" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-auth-demo-activity", + "module_src": "dbp-auth-demo-activity.js", + "routing_name": "auth", + "name": { + "de": "Authentifikation Komponente", + "en": "Authentication component" + }, + "short_name": { + "de": "Auth Komponente", + "en": "Auth component" + }, + "description": { + "de": "Web Komponente zur Authentifikation", + "en": "Auth web component" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/check-in-place-select.metadata.json b/toolkit-showcase/assets/check-in-place-select.metadata.json index 8647f4818e6213542877f69b394afdd6a3b6d3a7..10c30196453a3bec0b07509265bc4ced6dc74112 100644 --- a/toolkit-showcase/assets/check-in-place-select.metadata.json +++ b/toolkit-showcase/assets/check-in-place-select.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-check-in-place-select-demo-activity", - "module_src": "dbp-check-in-place-select-demo-activity.js", - "routing_name": "check-in-place-select", - "name": { - "de": "Ortauswahl", - "en": "Check-in place select" - }, - "short_name": { - "de": "Ortauswahl", - "en": "Check-in place select" - }, - "description": { - "de": "Ort Web Component", - "en": "Check-in place select web component" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-check-in-place-select-demo-activity", + "module_src": "dbp-check-in-place-select-demo-activity.js", + "routing_name": "check-in-place-select", + "name": { + "de": "Ortauswahl", + "en": "Check-in place select" + }, + "short_name": { + "de": "Ortauswahl", + "en": "Check-in place select" + }, + "description": { + "de": "Ort Web Component", + "en": "Check-in place select web component" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/common.metadata.json b/toolkit-showcase/assets/common.metadata.json index f536e1ecf4fd8b0e662d77ae1a79a48a5f9a2e6c..de1f70c7ede8728cc3cd6b0b8922da8137310763 100644 --- a/toolkit-showcase/assets/common.metadata.json +++ b/toolkit-showcase/assets/common.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-common-demo-activity", - "module_src": "dbp-common-demo-activity.js", - "routing_name": "common", - "name": { - "de": "Allgemeine Komponenten", - "en": "Common components" - }, - "short_name": { - "de": "Allgemeine Komponenten", - "en": "Common components" - }, - "description": { - "de": "Gemeinsame Web Components", - "en": "Common web components" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-common-demo-activity", + "module_src": "dbp-common-demo-activity.js", + "routing_name": "common", + "name": { + "de": "Allgemeine Komponenten", + "en": "Common components" + }, + "short_name": { + "de": "Allgemeine Komponenten", + "en": "Common components" + }, + "description": { + "de": "Gemeinsame Web Components", + "en": "Common web components" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/data-table-view.metadata.json b/toolkit-showcase/assets/data-table-view.metadata.json index afc1f01faad98169cd9325b62417cdcd5e5ef899..27e33d00b221be6bbef1f6618b2bea22372421b1 100644 --- a/toolkit-showcase/assets/data-table-view.metadata.json +++ b/toolkit-showcase/assets/data-table-view.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-data-table-view-demo-activity", - "module_src": "dbp-data-table-view-demo-activity.js", - "routing_name": "data-table-view", - "name": { - "de": "Data Table View", - "en": "Data table view" - }, - "short_name": { - "de": "Data Table View", - "en": "Data table view" - }, - "description": { - "de": "DataTable: mit Daten, Paginierung, Such- und Exportfunktion", - "en": "DataTable: with data, paging and searching AND exportable" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-data-table-view-demo-activity", + "module_src": "dbp-data-table-view-demo-activity.js", + "routing_name": "data-table-view", + "name": { + "de": "Data Table View", + "en": "Data table view" + }, + "short_name": { + "de": "Data Table View", + "en": "Data table view" + }, + "description": { + "de": "DataTable: mit Daten, Paginierung, Such- und Exportfunktion", + "en": "DataTable: with data, paging and searching AND exportable" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/file-handling.metadata.json b/toolkit-showcase/assets/file-handling.metadata.json index c9f3f735ea541201b9958743be0b16f77ea7883a..b6fa87b72db257b5ab92f32492fed1d2385c4a08 100644 --- a/toolkit-showcase/assets/file-handling.metadata.json +++ b/toolkit-showcase/assets/file-handling.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-file-handling-demo-activity", - "module_src": "dbp-file-handling-demo-activity.js", - "routing_name": "file-handling", - "name": { - "de": "File Handling", - "en": "File handling" - }, - "short_name": { - "de": "File Handling", - "en": "File handling" - }, - "description": { - "de": "Web Komponenten für file sink und file source. Für mehrere verschiedenen Quellen.", - "en": "Web components for file sink and file source. For several different sources." - }, - "subscribe": "lang,entry-point-url,nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url,file-handling-enabled-targets" + "element": "dbp-file-handling-demo-activity", + "module_src": "dbp-file-handling-demo-activity.js", + "routing_name": "file-handling", + "name": { + "de": "File Handling", + "en": "File handling" + }, + "short_name": { + "de": "File Handling", + "en": "File handling" + }, + "description": { + "de": "Web Komponenten für file sink und file source. Für mehrere verschiedenen Quellen.", + "en": "Web components for file sink and file source. For several different sources." + }, + "subscribe": "lang,entry-point-url,nextcloud-auth-url:nextcloud-auth-url,nextcloud-web-dav-url:nextcloud-web-dav-url,nextcloud-name:nextcloud-name,nextcloud-file-url:nextcloud-file-url,file-handling-enabled-targets" } diff --git a/toolkit-showcase/assets/knowledge-base-web-page-element-view.metadata.json b/toolkit-showcase/assets/knowledge-base-web-page-element-view.metadata.json index 904c8db941dda1b2dfcb6b9000f2fc178aaee1f1..e3af67e635e81fd1feea9ee594d0afc8b6f4d629 100644 --- a/toolkit-showcase/assets/knowledge-base-web-page-element-view.metadata.json +++ b/toolkit-showcase/assets/knowledge-base-web-page-element-view.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-knowledge-base-web-page-element-view-demo-activity", - "module_src": "dbp-knowledge-base-web-page-element-view-demo-activity.js", - "routing_name": "knowledge-base-web-page-element-view", - "name": { - "de": "Knowledgebase webpage element view", - "en": "Knowledgebase webpage element view" - }, - "short_name": { - "de": "Knowledgebase webpage element view", - "en": "Knowledgebase webpage element view" - }, - "description": { - "de": "Erlaubt das Einfügen von Webinhalten", - "en": "Allows the inserting of web content" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-knowledge-base-web-page-element-view-demo-activity", + "module_src": "dbp-knowledge-base-web-page-element-view-demo-activity.js", + "routing_name": "knowledge-base-web-page-element-view", + "name": { + "de": "Knowledgebase webpage element view", + "en": "Knowledgebase webpage element view" + }, + "short_name": { + "de": "Knowledgebase webpage element view", + "en": "Knowledgebase webpage element view" + }, + "description": { + "de": "Erlaubt das Einfügen von Webinhalten", + "en": "Allows the inserting of web content" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/language-select.metadata.json b/toolkit-showcase/assets/language-select.metadata.json index 1334dacefc0958883f8ec81dc2cee4436b939140..f55a5994793198fc00921dae80665b6d6687161a 100644 --- a/toolkit-showcase/assets/language-select.metadata.json +++ b/toolkit-showcase/assets/language-select.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-language-select-demo-activity", - "module_src": "dbp-language-select-demo-activity.js", - "routing_name": "language-select", - "name": { - "de": "Sprachauswahl", - "en": "Language select" - }, - "short_name": { - "de": "Sprachauswahl", - "en": "Language select" - }, - "description": { - "de": "Sprachauswahl Web Component", - "en": "Language select web component" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-language-select-demo-activity", + "module_src": "dbp-language-select-demo-activity.js", + "routing_name": "language-select", + "name": { + "de": "Sprachauswahl", + "en": "Language select" + }, + "short_name": { + "de": "Sprachauswahl", + "en": "Language select" + }, + "description": { + "de": "Sprachauswahl Web Component", + "en": "Language select web component" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/manifest.json b/toolkit-showcase/assets/manifest.json index 44a07efaf60d0ce8a972e5c40acf490af8a31cc1..3e62fa081af3ca80db916d580a4a1b1253e274f2 100644 --- a/toolkit-showcase/assets/manifest.json +++ b/toolkit-showcase/assets/manifest.json @@ -1,55 +1,55 @@ { - "short_name": "Toolkit Showcase", - "name": "Toolkit Showcase", - "start_url": "./", - "icons": [ - { - "src": "local/dbp-toolkit-showcase/icon-72x72.png", - "sizes": "72x72", - "type": "image/png" - }, - { - "src": "local/dbp-toolkit-showcase/icon-96x96.png", - "sizes": "96x96", - "type": "image/png" - }, - { - "src": "local/dbp-toolkit-showcase/icon-128x128.png", - "sizes": "128x128", - "type": "image/png" - }, - { - "src": "local/dbp-toolkit-showcase/icon-144x144.png", - "sizes": "144x144", - "type": "image/png" - }, - { - "src": "local/dbp-toolkit-showcase/icon-152x152.png", - "sizes": "152x152", - "type": "image/png" - }, - { - "src": "local/dbp-toolkit-showcase/icon-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "local/dbp-toolkit-showcase/icon-384x384.png", - "sizes": "384x384", - "type": "image/png" - }, - { - "src": "local/dbp-toolkit-showcase/icon-256x256.png", - "sizes": "256x256", - "type": "image/png" - }, - { - "src": "local/dbp-toolkit-showcase/icon-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "background_color": "#FEFEFE", - "display": "standalone", - "theme_color": "#FFFFFF" + "short_name": "Toolkit Showcase", + "name": "Toolkit Showcase", + "start_url": "./", + "icons": [ + { + "src": "local/dbp-toolkit-showcase/icon-72x72.png", + "sizes": "72x72", + "type": "image/png" + }, + { + "src": "local/dbp-toolkit-showcase/icon-96x96.png", + "sizes": "96x96", + "type": "image/png" + }, + { + "src": "local/dbp-toolkit-showcase/icon-128x128.png", + "sizes": "128x128", + "type": "image/png" + }, + { + "src": "local/dbp-toolkit-showcase/icon-144x144.png", + "sizes": "144x144", + "type": "image/png" + }, + { + "src": "local/dbp-toolkit-showcase/icon-152x152.png", + "sizes": "152x152", + "type": "image/png" + }, + { + "src": "local/dbp-toolkit-showcase/icon-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "local/dbp-toolkit-showcase/icon-384x384.png", + "sizes": "384x384", + "type": "image/png" + }, + { + "src": "local/dbp-toolkit-showcase/icon-256x256.png", + "sizes": "256x256", + "type": "image/png" + }, + { + "src": "local/dbp-toolkit-showcase/icon-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "background_color": "#FEFEFE", + "display": "standalone", + "theme_color": "#FFFFFF" } diff --git a/toolkit-showcase/assets/matomo.metadata.json b/toolkit-showcase/assets/matomo.metadata.json index ac6196b2499d153c3257662c47c99371ffcd0894..22bd70a46db9e9956c21f6ae6dbc147ccc9b5c68 100644 --- a/toolkit-showcase/assets/matomo.metadata.json +++ b/toolkit-showcase/assets/matomo.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-matomo-demo-activity", - "module_src": "dbp-matomo-demo-activity.js", - "routing_name": "matomo", - "name": { - "de": "Matomo", - "en": "Matomo" - }, - "short_name": { - "de": "Matomo", - "en": "Matomo" - }, - "description": { - "de": "Matomo Web Component", - "en": "Matomo web component" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-matomo-demo-activity", + "module_src": "dbp-matomo-demo-activity.js", + "routing_name": "matomo", + "name": { + "de": "Matomo", + "en": "Matomo" + }, + "short_name": { + "de": "Matomo", + "en": "Matomo" + }, + "description": { + "de": "Matomo Web Component", + "en": "Matomo web component" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/notification.metadata.json b/toolkit-showcase/assets/notification.metadata.json index c5e9627409643e0c2773e1aaee4f22d73fc8879e..12788d9aff68f981f0d75bd71770f0dfbd5d71a6 100644 --- a/toolkit-showcase/assets/notification.metadata.json +++ b/toolkit-showcase/assets/notification.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-notification-demo-activity", - "module_src": "dbp-notification-demo-activity.js", - "routing_name": "notification", - "name": { - "de": "Benachrichtigungen", - "en": "Notification" - }, - "short_name": { - "de": "Benachrichtigungen", - "en": "Notification" - }, - "description": { - "de": "Zeigt eine Benachrichtigung an", - "en": "Shows a message" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-notification-demo-activity", + "module_src": "dbp-notification-demo-activity.js", + "routing_name": "notification", + "name": { + "de": "Benachrichtigungen", + "en": "Notification" + }, + "short_name": { + "de": "Benachrichtigungen", + "en": "Notification" + }, + "description": { + "de": "Zeigt eine Benachrichtigung an", + "en": "Shows a message" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/organization-select.metadata.json b/toolkit-showcase/assets/organization-select.metadata.json index 93afba10fa3323120c3202c979be96266d75643c..d3684a7d4064e4ba32e3a77d1b4bc06ab865776d 100644 --- a/toolkit-showcase/assets/organization-select.metadata.json +++ b/toolkit-showcase/assets/organization-select.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-organization-select-demo-activity", - "module_src": "dbp-organization-select-demo-activity.js", - "routing_name": "organization-select", - "name": { - "de": "Institutsauswahl", - "en": "Organization select" - }, - "short_name": { - "de": "Institutsauswahl", - "en": "Organization select" - }, - "description": { - "de": "Erlaubt die Auswahl von Instituten", - "en": "Allows selection of organizations" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-organization-select-demo-activity", + "module_src": "dbp-organization-select-demo-activity.js", + "routing_name": "organization-select", + "name": { + "de": "Institutsauswahl", + "en": "Organization select" + }, + "short_name": { + "de": "Institutsauswahl", + "en": "Organization select" + }, + "description": { + "de": "Erlaubt die Auswahl von Instituten", + "en": "Allows selection of organizations" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/person-profile.metadata.json b/toolkit-showcase/assets/person-profile.metadata.json index 1a12b5cb70e3b12c8b7a5475dc809972c6e6944f..ff49c707e5606b18d17a7b2b7dbc564a47bf6338 100644 --- a/toolkit-showcase/assets/person-profile.metadata.json +++ b/toolkit-showcase/assets/person-profile.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-person-profile-demo-activity", - "module_src": "dbp-person-profile-demo-activity.js", - "routing_name": "person-profile", - "name": { - "de": "Personenprofil", - "en": "Person profile" - }, - "short_name": { - "de": "Personenprofil", - "en": "Person profile" - }, - "description": { - "de": "Gemeinsame Web Components", - "en": "Person profile web components" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-person-profile-demo-activity", + "module_src": "dbp-person-profile-demo-activity.js", + "routing_name": "person-profile", + "name": { + "de": "Personenprofil", + "en": "Person profile" + }, + "short_name": { + "de": "Personenprofil", + "en": "Person profile" + }, + "description": { + "de": "Gemeinsame Web Components", + "en": "Person profile web components" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/person-select.metadata.json b/toolkit-showcase/assets/person-select.metadata.json index 35c1d58d2683b4ad9bc97e8f3e05086afba252e4..6f1f19f6f4f642ad169045815384da499500a46a 100644 --- a/toolkit-showcase/assets/person-select.metadata.json +++ b/toolkit-showcase/assets/person-select.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-person-select-demo-activity", - "module_src": "dbp-person-select-demo-activity.js", - "routing_name": "person-select", - "name": { - "de": "Personensuche", - "en": "Person search" - }, - "short_name": { - "de": "Personensuche", - "en": "Person search" - }, - "description": { - "de": "Erlaubt das Suchen von Personen", - "en": "Allows searching for persons" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-person-select-demo-activity", + "module_src": "dbp-person-select-demo-activity.js", + "routing_name": "person-select", + "name": { + "de": "Personensuche", + "en": "Person search" + }, + "short_name": { + "de": "Personensuche", + "en": "Person search" + }, + "description": { + "de": "Erlaubt das Suchen von Personen", + "en": "Allows searching for persons" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/qr-code-scanner.metadata.json b/toolkit-showcase/assets/qr-code-scanner.metadata.json index ad5a59ff3e4c54e55870a55b12f3c50a9a17721a..c50ac83b64f391752f58f160f971efced33822f7 100644 --- a/toolkit-showcase/assets/qr-code-scanner.metadata.json +++ b/toolkit-showcase/assets/qr-code-scanner.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-qr-code-scanner-demo-activity", - "module_src": "dbp-qr-code-scanner-demo-activity.js", - "routing_name": "qr-code-scanner", - "name": { - "de": "QR Code Scanner", - "en": "QR Code Scanner" - }, - "short_name": { - "de": "QR Code Scanner", - "en": "QR Code Scanner" - }, - "description": { - "de": "Scannt Qr Codes", - "en": "Scans Qr Codes" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-qr-code-scanner-demo-activity", + "module_src": "dbp-qr-code-scanner-demo-activity.js", + "routing_name": "qr-code-scanner", + "name": { + "de": "QR Code Scanner", + "en": "QR Code Scanner" + }, + "short_name": { + "de": "QR Code Scanner", + "en": "QR Code Scanner" + }, + "description": { + "de": "Scannt Qr Codes", + "en": "Scans Qr Codes" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/assets/theme-switcher.metadata.json b/toolkit-showcase/assets/theme-switcher.metadata.json index 423846abe3658090047cfa73c0d2046e481ec52e..79d3bd989bf61fce3d9c681b3570b9ff734467d9 100644 --- a/toolkit-showcase/assets/theme-switcher.metadata.json +++ b/toolkit-showcase/assets/theme-switcher.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-theme-switcher-demo-activity", - "module_src": "dbp-theme-switcher-demo-activity.js", - "routing_name": "theme-switcher", - "name": { - "de": "Theme-Switcher Komponente", - "en": "Theme-switcher component" - }, - "short_name": { - "de": "Theme-Switcher Komponente", - "en": "Theme-switcher component" - }, - "description": { - "de": "Theme Switcher Web Komponente", - "en": "Theme-Switcher web component" - }, - "subscribe": "lang" + "element": "dbp-theme-switcher-demo-activity", + "module_src": "dbp-theme-switcher-demo-activity.js", + "routing_name": "theme-switcher", + "name": { + "de": "Theme-Switcher Komponente", + "en": "Theme-switcher component" + }, + "short_name": { + "de": "Theme-Switcher Komponente", + "en": "Theme-switcher component" + }, + "description": { + "de": "Theme Switcher Web Komponente", + "en": "Theme-Switcher web component" + }, + "subscribe": "lang" } diff --git a/toolkit-showcase/assets/tooltip.metadata.json b/toolkit-showcase/assets/tooltip.metadata.json index d4f5ca0f425a3c1ea0b70ff0891897f27a82ba36..087a96098c8a8671e397e331dab39345f6571e92 100644 --- a/toolkit-showcase/assets/tooltip.metadata.json +++ b/toolkit-showcase/assets/tooltip.metadata.json @@ -1,18 +1,18 @@ { - "element": "dbp-tooltip-demo-activity", - "module_src": "dbp-tooltip-demo-activity.js", - "routing_name": "tooltip", - "name": { - "de": "Tooltip Komponenten", - "en": "Tooltip components" - }, - "short_name": { - "de": "Tooltip Komponenten", - "en": "Tooltip components" - }, - "description": { - "de": "Tooltip Web Components", - "en": "Tooltip web components" - }, - "subscribe": "lang,entry-point-url" + "element": "dbp-tooltip-demo-activity", + "module_src": "dbp-tooltip-demo-activity.js", + "routing_name": "tooltip", + "name": { + "de": "Tooltip Komponenten", + "en": "Tooltip components" + }, + "short_name": { + "de": "Tooltip Komponenten", + "en": "Tooltip components" + }, + "description": { + "de": "Tooltip Web Components", + "en": "Tooltip web components" + }, + "subscribe": "lang,entry-point-url" } diff --git a/toolkit-showcase/package.json b/toolkit-showcase/package.json index bb8b40ab661fc603013c0f246950a0e1ca901883..80ea92cd459d9ebb709ae5a4cb76f53ad78af751 100644 --- a/toolkit-showcase/package.json +++ b/toolkit-showcase/package.json @@ -1,66 +1,70 @@ { - "name": "dbp-toolkit-showcase", - "version": "0.2.0", - "main": "src/toolkit-showcase.js", - "license": "LGPL-2.1-or-later", - "private": true, - "devDependencies": { - "@babel/core": "^7.10.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.10.1", - "@babel/plugin-transform-runtime": "^7.10.3", - "@babel/preset-env": "^7.10.3", - "@babel/runtime-corejs3": "^7.10.3", - "@esm-bundle/chai": "^4.2.0", - "@rollup/plugin-babel": "^5.0.4", - "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-url": "^6.0.0", - "chokidar": "^3.4.0", - "eslint": "^8.0.0", - "eslint-plugin-jsdoc": "^37.0.0", - "find-cache-dir": "^3.3.1", - "glob": "^7.1.6", - "i18next-scanner": "^3.0.0", - "karma": "^6.0.0", - "karma-chrome-launcher": "^3.1.0", - "karma-firefox-launcher": "^2.1.0", - "karma-mocha": "^2.0.1", - "mocha": "^9.0.0", - "rollup": "^2.18.1", - "rollup-plugin-copy": "^3.3.0", - "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-emit-ejs": "^3.1.0", - "rollup-plugin-license": "^2.1.0", - "rollup-plugin-md": "^1.0.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2", - "selfsigned": "^2.0.0" - }, - "dependencies": { - "@dbp-toolkit/app-shell": "^0.2.0", - "@dbp-toolkit/auth": "^0.2.0", - "@dbp-toolkit/common": "^0.2.0", - "@dbp-toolkit/file-handling": "^0.2.0", - "@dbp-toolkit/font-source-sans-pro": "^0.2.0", - "@dbp-toolkit/language-select": "^0.2.0", - "@dbp-toolkit/notification": "^0.2.0", - "@dbp-toolkit/organization-select": "^0.2.0", - "@dbp-toolkit/person-profile": "^0.2.0", - "@dbp-toolkit/person-select": "^0.2.0", - "@open-wc/scoped-elements": "^2.0.0", - "@rollup/plugin-replace": "^3.0.0", - "highlight.js": "^11.0.0", - "lit": "^2.0.0" - }, - "scripts": { - "build": "rollup -c", - "i18next": "i18next-scanner", - "watch": "rollup -c --watch", - "watch-local": "yarn run watch", - "watch-full": "rollup -c --watch --environment FORCE_FULL", - "watch-bs": "rollup -c --watch --environment APP_ENV:bs", - "lint": "eslint ." - } + "name": "dbp-toolkit-showcase", + "version": "0.2.0", + "main": "src/toolkit-showcase.js", + "license": "LGPL-2.1-or-later", + "private": true, + "devDependencies": { + "@babel/core": "^7.10.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.10.1", + "@babel/plugin-transform-runtime": "^7.10.3", + "@babel/preset-env": "^7.10.3", + "@babel/runtime-corejs3": "^7.10.3", + "@esm-bundle/chai": "^4.2.0", + "@rollup/plugin-babel": "^5.0.4", + "@rollup/plugin-commonjs": "^21.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-url": "^6.0.0", + "chokidar": "^3.4.0", + "eslint": "^8.0.0", + "eslint-plugin-jsdoc": "^37.0.0", + "find-cache-dir": "^3.3.1", + "glob": "^7.1.6", + "i18next-scanner": "^3.0.0", + "karma": "^6.0.0", + "karma-chrome-launcher": "^3.1.0", + "karma-firefox-launcher": "^2.1.0", + "karma-mocha": "^2.0.1", + "mocha": "^9.0.0", + "prettier": "^2.5.1", + "rollup": "^2.18.1", + "rollup-plugin-copy": "^3.3.0", + "rollup-plugin-delete": "^2.0.0", + "rollup-plugin-emit-ejs": "^3.1.0", + "rollup-plugin-license": "^2.1.0", + "rollup-plugin-md": "^1.0.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^7.0.2", + "selfsigned": "^2.0.0" + }, + "dependencies": { + "@dbp-toolkit/app-shell": "^0.2.0", + "@dbp-toolkit/auth": "^0.2.0", + "@dbp-toolkit/common": "^0.2.0", + "@dbp-toolkit/file-handling": "^0.2.0", + "@dbp-toolkit/font-source-sans-pro": "^0.2.0", + "@dbp-toolkit/language-select": "^0.2.0", + "@dbp-toolkit/notification": "^0.2.0", + "@dbp-toolkit/organization-select": "^0.2.0", + "@dbp-toolkit/person-profile": "^0.2.0", + "@dbp-toolkit/person-select": "^0.2.0", + "@open-wc/scoped-elements": "^2.0.0", + "@rollup/plugin-replace": "^3.0.0", + "highlight.js": "^11.0.0", + "lit": "^2.0.0" + }, + "scripts": { + "build": "rollup -c", + "format": "yarn run format:eslint && yarn run format:prettier", + "format:eslint": "eslint \"**/*.{js,ts}\" --fix", + "format:prettier": "prettier \"**/*.{js,json,ts}\" --write", + "i18next": "i18next-scanner", + "watch": "rollup -c --watch", + "watch-local": "yarn run watch", + "watch-full": "rollup -c --watch --environment FORCE_FULL", + "watch-bs": "rollup -c --watch --environment APP_ENV:bs", + "lint": "eslint ." + } } diff --git a/toolkit-showcase/rollup.config.js b/toolkit-showcase/rollup.config.js index 7f0d428f9fb30e804cbb6ea8877b87b3fec919c8..14e841141c2c4858e0ff2d449ca82d5053336f78 100644 --- a/toolkit-showcase/rollup.config.js +++ b/toolkit-showcase/rollup.config.js @@ -4,29 +4,29 @@ import glob from 'glob'; 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 {terser} from 'rollup-plugin-terser'; import json from '@rollup/plugin-json'; import serve from 'rollup-plugin-serve'; -import urlPlugin from "@rollup/plugin-url"; +import urlPlugin from '@rollup/plugin-url'; import license from 'rollup-plugin-license'; import del from 'rollup-plugin-delete'; import md from 'rollup-plugin-md'; -import emitEJS from 'rollup-plugin-emit-ejs' +import emitEJS from 'rollup-plugin-emit-ejs'; import {getBabelOutputPlugin} from '@rollup/plugin-babel'; import appConfig from './app.config.js'; import {generateTLSConfig, getBuildInfo, getPackagePath, getDistPath} from '../rollup.utils.js'; import replace from 'rollup-plugin-replace'; const pkg = require('./package.json'); -const appEnv = (typeof process.env.APP_ENV !== 'undefined') ? process.env.APP_ENV : 'local'; +const appEnv = typeof process.env.APP_ENV !== 'undefined' ? process.env.APP_ENV : 'local'; const watch = process.env.ROLLUP_WATCH === 'true'; -const buildFull = (!watch && appEnv !== 'test') || (process.env.FORCE_FULL !== undefined); +const buildFull = (!watch && appEnv !== 'test') || process.env.FORCE_FULL !== undefined; let useTerser = buildFull; let useBabel = buildFull; let checkLicenses = buildFull; let useHTTPS = true; -console.log("APP_ENV: " + appEnv); +console.log('APP_ENV: ' + appEnv); let config; if (appEnv in appConfig) { @@ -59,152 +59,196 @@ if (config.nextcloudBaseURL) { } function getOrigin(url) { - if (url) - return new URL(url).origin; + if (url) return new URL(url).origin; return ''; } config.CSP = `default-src 'self' 'unsafe-eval' 'unsafe-inline' \ -${getOrigin(config.matomoUrl)} ${getOrigin(config.keyCloakBaseURL)} ${getOrigin(config.entryPointURL)} \ +${getOrigin(config.matomoUrl)} ${getOrigin(config.keyCloakBaseURL)} ${getOrigin( + config.entryPointURL +)} \ httpbin.org ${getOrigin(config.nextcloudBaseURL)}; \ img-src * blob: data:`; - export default (async () => { - let privatePath = await getDistPath(pkg.name) + let privatePath = await getDistPath(pkg.name); return { - input: (appEnv != 'test') ? glob.sync('src/dbp-*.js') : glob.sync('test/**/*.js'), - output: { - dir: 'dist', - entryFileNames: '[name].js', - chunkFileNames: 'shared/[name].[hash].[format].js', - format: 'esm', - sourcemap: true - }, - preserveEntrySignatures: false, - plugins: [ - del({ - targets: 'dist/*' - }), - emitEJS({ - src: 'assets', - include: ['**/*.ejs', '**/.*.ejs'], - data: { - getUrl: (p) => { - return url.resolve(config.basePath, p); - }, - getPrivateUrl: (p) => { - return url.resolve(`${config.basePath}${privatePath}/`, p); - }, - name: pkg.name, - entryPointURL: config.entryPointURL, - nextcloudBaseURL: config.nextcloudBaseURL, - nextcloudWebAppPasswordURL: config.nextcloudWebAppPasswordURL, - nextcloudWebDavURL: config.nextcloudWebDavURL, - nextcloudFileURL: config.nextcloudFileURL, - nextcloudName: config.nextcloudName, - keyCloakBaseURL: config.keyCloakBaseURL, - keyCloakRealm: config.keyCloakRealm, - keyCloakClientId: config.keyCloakClientId, - CSP: config.CSP, - matomoUrl: config.matomoUrl, - matomoSiteId: config.matomoSiteId, - buildInfo: getBuildInfo(appEnv) - } - }), - resolve({ - browser: true, - preferBuiltins: true - }), - checkLicenses && license({ - banner: { - commentStyle: 'ignored', - content: ` + input: appEnv != 'test' ? glob.sync('src/dbp-*.js') : glob.sync('test/**/*.js'), + output: { + dir: 'dist', + entryFileNames: '[name].js', + chunkFileNames: 'shared/[name].[hash].[format].js', + format: 'esm', + sourcemap: true, + }, + preserveEntrySignatures: false, + plugins: [ + del({ + targets: 'dist/*', + }), + emitEJS({ + src: 'assets', + include: ['**/*.ejs', '**/.*.ejs'], + data: { + getUrl: (p) => { + return url.resolve(config.basePath, p); + }, + getPrivateUrl: (p) => { + return url.resolve(`${config.basePath}${privatePath}/`, p); + }, + name: pkg.name, + entryPointURL: config.entryPointURL, + nextcloudBaseURL: config.nextcloudBaseURL, + nextcloudWebAppPasswordURL: config.nextcloudWebAppPasswordURL, + nextcloudWebDavURL: config.nextcloudWebDavURL, + nextcloudFileURL: config.nextcloudFileURL, + nextcloudName: config.nextcloudName, + keyCloakBaseURL: config.keyCloakBaseURL, + keyCloakRealm: config.keyCloakRealm, + keyCloakClientId: config.keyCloakClientId, + CSP: config.CSP, + matomoUrl: config.matomoUrl, + matomoSiteId: config.matomoSiteId, + buildInfo: getBuildInfo(appEnv), + }, + }), + resolve({ + browser: true, + preferBuiltins: true, + }), + checkLicenses && + license({ + banner: { + commentStyle: 'ignored', + content: ` License: <%= pkg.license %> Dependencies: <% _.forEach(dependencies, function (dependency) { if (dependency.name) { %> <%= dependency.name %>: <%= dependency.license %><% }}) %> -`}, - thirdParty: { - allow: { - test: '(MIT OR BSD-3-Clause OR Apache-2.0 OR LGPL-2.1-or-later OR 0BSD)', - failOnUnlicensed: true, - failOnViolation: true, - }, - }, - }), - commonjs(), - json(), - md({ - include: ["../../**/*.md"], - marked: { - highlight: function(code) { - return require('highlight.js').highlightAuto(code).value; - } - } - }), - urlPlugin({ - limit: 0, - include: [ - await getPackagePath('select2', '**/*.css'), - await getPackagePath('highlight.js', '**/*.css'), - await getPackagePath('tippy.js', '**/*.css'), - ], - emitFiles: true, - fileName: 'shared/[name].[hash][extname]' - }), - useTerser ? terser() : false, - copy({ - targets: [ - {src: 'assets/*.css', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: 'assets/*.ico', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: 'assets/*.metadata.json', dest: 'dist'}, - {src: 'assets/*.svg', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: 'assets/htaccess-shared', dest: 'dist/shared/', rename: '.htaccess'}, - {src: 'assets/icon-*.png', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: 'assets/apple-*.png', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: 'assets/safari-*.svg', dest: 'dist/' + await getDistPath(pkg.name)}, - {src: 'assets/manifest.json', dest: 'dist', rename: pkg.name + '.manifest.json'}, - {src: 'assets/silent-check-sso.html', dest:'dist'}, - {src: await getPackagePath('@dbp-toolkit/font-source-sans-pro', 'files/*'), dest: 'dist/' + await getDistPath(pkg.name, 'fonts/source-sans-pro')}, - {src: await getPackagePath('@dbp-toolkit/common', 'src/spinner.js'), dest: 'dist/' + await getDistPath(pkg.name)}, - {src: await getPackagePath('@dbp-toolkit/common', 'misc/browser-check.js'), dest: 'dist/' + await getDistPath(pkg.name)}, - {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, - {src: await getPackagePath('tabulator-tables', 'dist/css'), dest: 'dist/' + await getDistPath('@dbp-toolkit/file-handling', 'tabulator-tables')}, - {src: await getPackagePath('qr-scanner', 'qr-scanner-worker.*'), dest: 'dist/' + await getDistPath('@dbp-toolkit/qr-code-scanner')}, - {src: await getPackagePath('datatables.net-dt', 'css'), dest: 'dist/' + await getDistPath('@dbp-toolkit/data-table-view')}, - {src: await getPackagePath('datatables.net-dt', 'images'), dest: 'dist/' + await getDistPath('@dbp-toolkit/data-table-view')}, - {src: await getPackagePath('datatables.net-responsive-dt', 'css'), dest: 'dist/' + await getDistPath('@dbp-toolkit/data-table-view')}, - {src: await getPackagePath('datatables.net-buttons-dt', 'css'), dest: 'dist/' + await getDistPath('@dbp-toolkit/data-table-view')}, - ], - }), - replace({ - 'process.env.NODE_ENV': JSON.stringify('production') - }), - useBabel && getBabelOutputPlugin({ - compact: false, - presets: [[ - '@babel/preset-env', { - loose: true, - shippedProposals: true, - bugfixes: true, - modules: false, - targets: { - esmodules: true - } - } - ]], - }), - watch ? serve({ - contentBase: '.', - host: '127.0.0.1', - port: 8001, - historyApiFallback: config.basePath + pkg.name + '.html', - https: useHTTPS ? await generateTLSConfig() : false, - headers: { - 'Content-Security-Policy': config.CSP - }, - }) : false - ] -};})(); - +`, + }, + thirdParty: { + allow: { + test: '(MIT OR BSD-3-Clause OR Apache-2.0 OR LGPL-2.1-or-later OR 0BSD)', + failOnUnlicensed: true, + failOnViolation: true, + }, + }, + }), + commonjs(), + json(), + md({ + include: ['../../**/*.md'], + marked: { + highlight: function (code) { + return require('highlight.js').highlightAuto(code).value; + }, + }, + }), + urlPlugin({ + limit: 0, + include: [ + await getPackagePath('select2', '**/*.css'), + await getPackagePath('highlight.js', '**/*.css'), + await getPackagePath('tippy.js', '**/*.css'), + ], + emitFiles: true, + fileName: 'shared/[name].[hash][extname]', + }), + useTerser ? terser() : false, + copy({ + targets: [ + {src: 'assets/*.css', dest: 'dist/' + (await getDistPath(pkg.name))}, + {src: 'assets/*.ico', dest: 'dist/' + (await getDistPath(pkg.name))}, + {src: 'assets/*.metadata.json', dest: 'dist'}, + {src: 'assets/*.svg', dest: 'dist/' + (await getDistPath(pkg.name))}, + {src: 'assets/htaccess-shared', dest: 'dist/shared/', rename: '.htaccess'}, + {src: 'assets/icon-*.png', dest: 'dist/' + (await getDistPath(pkg.name))}, + {src: 'assets/apple-*.png', dest: 'dist/' + (await getDistPath(pkg.name))}, + {src: 'assets/safari-*.svg', dest: 'dist/' + (await getDistPath(pkg.name))}, + { + src: 'assets/manifest.json', + dest: 'dist', + rename: pkg.name + '.manifest.json', + }, + {src: 'assets/silent-check-sso.html', dest: 'dist'}, + { + src: await getPackagePath('@dbp-toolkit/font-source-sans-pro', 'files/*'), + dest: 'dist/' + (await getDistPath(pkg.name, 'fonts/source-sans-pro')), + }, + { + src: await getPackagePath('@dbp-toolkit/common', 'src/spinner.js'), + dest: 'dist/' + (await getDistPath(pkg.name)), + }, + { + src: await getPackagePath('@dbp-toolkit/common', 'misc/browser-check.js'), + dest: 'dist/' + (await getDistPath(pkg.name)), + }, + { + src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/common', 'icons')), + }, + { + src: await getPackagePath('tabulator-tables', 'dist/css'), + dest: + 'dist/' + + (await getDistPath('@dbp-toolkit/file-handling', 'tabulator-tables')), + }, + { + src: await getPackagePath('qr-scanner', 'qr-scanner-worker.*'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/qr-code-scanner')), + }, + { + src: await getPackagePath('datatables.net-dt', 'css'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/data-table-view')), + }, + { + src: await getPackagePath('datatables.net-dt', 'images'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/data-table-view')), + }, + { + src: await getPackagePath('datatables.net-responsive-dt', 'css'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/data-table-view')), + }, + { + src: await getPackagePath('datatables.net-buttons-dt', 'css'), + dest: 'dist/' + (await getDistPath('@dbp-toolkit/data-table-view')), + }, + ], + }), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production'), + }), + useBabel && + getBabelOutputPlugin({ + compact: false, + presets: [ + [ + '@babel/preset-env', + { + loose: true, + shippedProposals: true, + bugfixes: true, + modules: false, + targets: { + esmodules: true, + }, + }, + ], + ], + }), + watch + ? serve({ + contentBase: '.', + host: '127.0.0.1', + port: 8001, + historyApiFallback: config.basePath + pkg.name + '.html', + https: useHTTPS ? await generateTLSConfig() : false, + headers: { + 'Content-Security-Policy': config.CSP, + }, + }) + : false, + ], + }; +})(); diff --git a/toolkit-showcase/src/dbp-auth-demo-activity.js b/toolkit-showcase/src/dbp-auth-demo-activity.js index 2c7f3ce6597e9d5d5a4d7dc9364feed16f65afab..617dd4b366d4fe98424ab5478f42955bd93b5fb3 100644 --- a/toolkit-showcase/src/dbp-auth-demo-activity.js +++ b/toolkit-showcase/src/dbp-auth-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/auth/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpAuthDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpAuthDemoActivity extends ScopedElementsMixin(AdapterLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,22 +42,30 @@ class DbpAuthDemoActivity extends ScopedElementsMixin(AdapterLitElement) { commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-auth-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" subscribe="auth" no-auth></dbp-auth-demo> + ${unsafeHTML(readme)} + <dbp-auth-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + subscribe="auth" + no-auth></dbp-auth-demo> `; } } diff --git a/toolkit-showcase/src/dbp-check-in-place-select-demo-activity.js b/toolkit-showcase/src/dbp-check-in-place-select-demo-activity.js index d098a750000458fce7f7cb91debfeae2c51af655..5dabc05fe9cf1a479fbc0339ee937f7f892b9636 100644 --- a/toolkit-showcase/src/dbp-check-in-place-select-demo-activity.js +++ b/toolkit-showcase/src/dbp-check-in-place-select-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/check-in-place-select/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,24 +42,34 @@ class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-check-in-place-select-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" no-auth></dbp-check-in-place-select-demo> + ${unsafeHTML(readme)} + <dbp-check-in-place-select-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + no-auth></dbp-check-in-place-select-demo> `; } } -commonUtils.defineCustomElement('dbp-check-in-place-select-demo-activity', DbpActivityNameDemoActivity); +commonUtils.defineCustomElement( + 'dbp-check-in-place-select-demo-activity', + DbpActivityNameDemoActivity +); diff --git a/toolkit-showcase/src/dbp-common-demo-activity.js b/toolkit-showcase/src/dbp-common-demo-activity.js index 9f9330a6f89f25045eac98c4653431fe2a6a6832..fc633b9d37f5ba3362f6bbe99f6b75f8ab107010 100644 --- a/toolkit-showcase/src/dbp-common-demo-activity.js +++ b/toolkit-showcase/src/dbp-common-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/common/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpCommonDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpCommonDemoActivity extends ScopedElementsMixin(AdapterLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,22 +42,28 @@ class DbpCommonDemoActivity extends ScopedElementsMixin(AdapterLitElement) { commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-common-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-common-demo> + ${unsafeHTML(readme)} + <dbp-common-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}"></dbp-common-demo> `; } } diff --git a/toolkit-showcase/src/dbp-data-table-view-demo-activity.js b/toolkit-showcase/src/dbp-data-table-view-demo-activity.js index f54e36fd745fac43b69c364c6881c8d6ef42eed7..ae4841e414dcbbad017300a254a8c76ee0a2e3bb 100644 --- a/toolkit-showcase/src/dbp-data-table-view-demo-activity.js +++ b/toolkit-showcase/src/dbp-data-table-view-demo-activity.js @@ -5,10 +5,11 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/data-table-view/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; -class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) { //TODO +class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) { + //TODO constructor() { super(); this.lang = 'en'; @@ -24,16 +25,15 @@ class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,23 +43,29 @@ class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - - ${unsafeHTML(readme)} - <dbp-data-table-view-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" no-auth></dbp-data-table-view-demo> + ${unsafeHTML(readme)} + <dbp-data-table-view-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + no-auth></dbp-data-table-view-demo> `; } } diff --git a/toolkit-showcase/src/dbp-demo-template.js b/toolkit-showcase/src/dbp-demo-template.js index 620eae32a57821a0e4b5701654d2a83d74683b77..7b19ef26759975b958ccee10dcc590523fafde10 100644 --- a/toolkit-showcase/src/dbp-demo-template.js +++ b/toolkit-showcase/src/dbp-demo-template.js @@ -5,10 +5,11 @@ import * as commonStyles from '@dbp-toolkit/common/styles'; //import * as commonUtils from "@dbp-toolkit/common/utils"; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; // import readme from '@dbp-toolkit/class-name/README.md'; TODO -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; -export class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) { //TODO +export class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitElement) { + //TODO constructor() { super(); this.lang = 'en'; @@ -25,16 +26,15 @@ export class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitE static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -44,24 +44,28 @@ export class DbpActivityNameDemoActivity extends ScopedElementsMixin(AdapterLitE commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - <!-- + <!-- TODO ${unsafeHTML('readme')} - <dbp-class-name-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-class-name-demo> + <dbp-class-name-demo id="demo" lang="${this.lang}" entry-point-url="${this + .entryPointUrl}"></dbp-class-name-demo> --> `; } diff --git a/toolkit-showcase/src/dbp-file-handling-demo-activity.js b/toolkit-showcase/src/dbp-file-handling-demo-activity.js index 3d0b26f93e3bbd3674428b94f0ce5c9943fda36e..b50d9b9c5f30280efb67b9b62f509ec09da79f28 100644 --- a/toolkit-showcase/src/dbp-file-handling-demo-activity.js +++ b/toolkit-showcase/src/dbp-file-handling-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/file-handling/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpFileHandlingDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpFileHandlingDemoActivity extends ScopedElementsMixin(AdapterLitElement) static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,22 +42,28 @@ class DbpFileHandlingDemoActivity extends ScopedElementsMixin(AdapterLitElement) commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-file-handling-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-file-handling-demo> + ${unsafeHTML(readme)} + <dbp-file-handling-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}"></dbp-file-handling-demo> `; } } diff --git a/toolkit-showcase/src/dbp-knowledge-base-web-page-element-view-demo-activity.js b/toolkit-showcase/src/dbp-knowledge-base-web-page-element-view-demo-activity.js index 3ded518de2132d73b204667f6b68c9db9d47924f..b0b4906c36bab2cfafaa2ebb7cd26ff5ca5334ed 100644 --- a/toolkit-showcase/src/dbp-knowledge-base-web-page-element-view-demo-activity.js +++ b/toolkit-showcase/src/dbp-knowledge-base-web-page-element-view-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/knowledge-base-web-page-element-view/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class KnowledgeBaseWebPageElementViewDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class KnowledgeBaseWebPageElementViewDemoActivity extends ScopedElementsMixin(Ad static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,24 +42,34 @@ class KnowledgeBaseWebPageElementViewDemoActivity extends ScopedElementsMixin(Ad commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-knowledge-base-web-page-element-view-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" no-auth></dbp-knowledge-base-web-page-element-view-demo> + ${unsafeHTML(readme)} + <dbp-knowledge-base-web-page-element-view-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + no-auth></dbp-knowledge-base-web-page-element-view-demo> `; } } -commonUtils.defineCustomElement('dbp-knowledge-base-web-page-element-view-demo-activity', KnowledgeBaseWebPageElementViewDemoActivity); +commonUtils.defineCustomElement( + 'dbp-knowledge-base-web-page-element-view-demo-activity', + KnowledgeBaseWebPageElementViewDemoActivity +); diff --git a/toolkit-showcase/src/dbp-language-select-demo-activity.js b/toolkit-showcase/src/dbp-language-select-demo-activity.js index 509a20390387cdc0495f747f377d6cf55be3e38b..b8a693feafbb6f3fa2197d9c253c01e6fe6072b0 100644 --- a/toolkit-showcase/src/dbp-language-select-demo-activity.js +++ b/toolkit-showcase/src/dbp-language-select-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/language-select/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpLanguageSelectDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpLanguageSelectDemoActivity extends ScopedElementsMixin(AdapterLitElemen static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,24 +42,28 @@ class DbpLanguageSelectDemoActivity extends ScopedElementsMixin(AdapterLitElemen commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - - ${unsafeHTML(readme)} - <dbp-language-select-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-language-select-demo> - + ${unsafeHTML(readme)} + <dbp-language-select-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}"></dbp-language-select-demo> `; } } diff --git a/toolkit-showcase/src/dbp-matomo-demo-activity.js b/toolkit-showcase/src/dbp-matomo-demo-activity.js index ec4aaeaae92f71eac40d3768178bd53116e48c9d..fbdb7a20b7a3698e6e11d31fc3e9f06a0257d5ab 100644 --- a/toolkit-showcase/src/dbp-matomo-demo-activity.js +++ b/toolkit-showcase/src/dbp-matomo-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/matomo/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpMatomoDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpMatomoDemoActivity extends ScopedElementsMixin(AdapterLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,22 +42,29 @@ class DbpMatomoDemoActivity extends ScopedElementsMixin(AdapterLitElement) { commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-matomo-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" no-auth></dbp-matomo-demo> + ${unsafeHTML(readme)} + <dbp-matomo-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + no-auth></dbp-matomo-demo> `; } } diff --git a/toolkit-showcase/src/dbp-notification-demo-activity.js b/toolkit-showcase/src/dbp-notification-demo-activity.js index 0cbee6830a1fdf9d62203f6f0e0f7a3df43b3860..5aff1dab5fed52b36322b22e1475f82c63dd78ee 100644 --- a/toolkit-showcase/src/dbp-notification-demo-activity.js +++ b/toolkit-showcase/src/dbp-notification-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/notification/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpNotificationDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpNotificationDemoActivity extends ScopedElementsMixin(AdapterLitElement) static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,22 +42,28 @@ class DbpNotificationDemoActivity extends ScopedElementsMixin(AdapterLitElement) commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-notification-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-notification-demo> + ${unsafeHTML(readme)} + <dbp-notification-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}"></dbp-notification-demo> `; } } diff --git a/toolkit-showcase/src/dbp-organization-select-demo-activity.js b/toolkit-showcase/src/dbp-organization-select-demo-activity.js index 061664ab15d8a4e8d91b4a1096111238804cc871..466429fb059c462df2590bb3a58caac469b52844 100644 --- a/toolkit-showcase/src/dbp-organization-select-demo-activity.js +++ b/toolkit-showcase/src/dbp-organization-select-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/organization-select/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpOrganizationSelectDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -17,23 +17,22 @@ class DbpOrganizationSelectDemoActivity extends ScopedElementsMixin(AdapterLitEl static get scopedElements() { return { - 'dbp-organization-select-demo': OrganizationSelectDemo, + 'dbp-organization-select-demo': OrganizationSelectDemo, }; } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,24 +42,34 @@ class DbpOrganizationSelectDemoActivity extends ScopedElementsMixin(AdapterLitEl commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` ${unsafeHTML(readme)} - <dbp-organization-select-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" no-auth></dbp-organization-select-demo> + <dbp-organization-select-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + no-auth></dbp-organization-select-demo> `; } } -commonUtils.defineCustomElement('dbp-organization-select-demo-activity', DbpOrganizationSelectDemoActivity); +commonUtils.defineCustomElement( + 'dbp-organization-select-demo-activity', + DbpOrganizationSelectDemoActivity +); diff --git a/toolkit-showcase/src/dbp-person-profile-demo-activity.js b/toolkit-showcase/src/dbp-person-profile-demo-activity.js index 8186f01ad7a01b5427bdbdf59b9462a6bec4f5f8..5ca7aac9595c47acd03e5b98c3a1099de64f3783 100644 --- a/toolkit-showcase/src/dbp-person-profile-demo-activity.js +++ b/toolkit-showcase/src/dbp-person-profile-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/person-profile/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpPersonProfileDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpPersonProfileDemoActivity extends ScopedElementsMixin(AdapterLitElement static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,23 +42,29 @@ class DbpPersonProfileDemoActivity extends ScopedElementsMixin(AdapterLitElement commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-person-profile-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" no-auth></dbp-person-profile-demo> - + ${unsafeHTML(readme)} + <dbp-person-profile-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + no-auth></dbp-person-profile-demo> `; } } diff --git a/toolkit-showcase/src/dbp-person-select-demo-activity.js b/toolkit-showcase/src/dbp-person-select-demo-activity.js index 742a1f3da0183bca884836fc0b2ada3e2f36184a..6dc5bbcd6aab72bef429d80ce57a0a840633dfd6 100644 --- a/toolkit-showcase/src/dbp-person-select-demo-activity.js +++ b/toolkit-showcase/src/dbp-person-select-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/person-select/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpPersonSelectDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -17,23 +17,22 @@ class DbpPersonSelectDemoActivity extends ScopedElementsMixin(AdapterLitElement) static get scopedElements() { return { - 'dbp-person-select-demo': PersonSelectDemo, + 'dbp-person-select-demo': PersonSelectDemo, }; } static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,22 +42,29 @@ class DbpPersonSelectDemoActivity extends ScopedElementsMixin(AdapterLitElement) commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` ${unsafeHTML(readme)} - <dbp-person-select-demo id="demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}" no-auth></dbp-person-select-demo> + <dbp-person-select-demo + id="demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}" + no-auth></dbp-person-select-demo> `; } } diff --git a/toolkit-showcase/src/dbp-qr-code-scanner-demo-activity.js b/toolkit-showcase/src/dbp-qr-code-scanner-demo-activity.js index 9a9afcf13c35bfb10c3d03ac9f6fe8e1fa7e0f5f..d4a26c46fec023c09d6ade3467dc53d1327dcf56 100644 --- a/toolkit-showcase/src/dbp-qr-code-scanner-demo-activity.js +++ b/toolkit-showcase/src/dbp-qr-code-scanner-demo-activity.js @@ -6,7 +6,7 @@ import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/qr-code-scanner/README.md'; import * as demoStyles from './styles'; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpQrCodeScannerDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -24,16 +24,15 @@ class DbpQrCodeScannerDemoActivity extends ScopedElementsMixin(AdapterLitElement static get properties() { return { ...super.properties, - lang: { type: String }, - entryPointUrl: { type: String, attribute: 'entry-point-url' }, + lang: {type: String}, + entryPointUrl: {type: String, attribute: 'entry-point-url'}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -43,19 +42,21 @@ class DbpQrCodeScannerDemoActivity extends ScopedElementsMixin(AdapterLitElement commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - - #scanner-demo{ - display: block; - padding-top: 50px; - } - ` + #scanner-demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` ${unsafeHTML(readme)} - <dbp-qr-code-scanner-demo id="scanner-demo" lang="${this.lang}" entry-point-url="${this.entryPointUrl}"></dbp-qr-code-scanner-demo> + <dbp-qr-code-scanner-demo + id="scanner-demo" + lang="${this.lang}" + entry-point-url="${this.entryPointUrl}"></dbp-qr-code-scanner-demo> `; } } diff --git a/toolkit-showcase/src/dbp-theme-switcher-demo-activity.js b/toolkit-showcase/src/dbp-theme-switcher-demo-activity.js index 2791fabd6f8b62d7104d187b4e14dc5d900ff4fc..7ff3ca1954d5c66751f10110a19e6e75e6091b65 100644 --- a/toolkit-showcase/src/dbp-theme-switcher-demo-activity.js +++ b/toolkit-showcase/src/dbp-theme-switcher-demo-activity.js @@ -2,11 +2,11 @@ import {css, html} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {ThemeSwitcherDemo} from '@dbp-toolkit/theme-switcher/src/demo'; import * as commonStyles from '@dbp-toolkit/common/styles'; -import * as commonUtils from "@dbp-toolkit/common/utils"; +import * as commonUtils from '@dbp-toolkit/common/utils'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/theme-switcher/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; export class DbpThemeSwitcherDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -23,15 +23,14 @@ export class DbpThemeSwitcherDemoActivity extends ScopedElementsMixin(AdapterLit static get properties() { return { ...super.properties, - lang: { type: String } + lang: {type: String}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -41,22 +40,25 @@ export class DbpThemeSwitcherDemoActivity extends ScopedElementsMixin(AdapterLit commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ - display: block; - padding-top: 50px; - } - - ` + #demo { + display: block; + padding-top: 50px; + } + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-theme-switcher-demo id="demo" lang="${this.lang}"></dbp-theme-switcher-demo> + ${unsafeHTML(readme)} + <dbp-theme-switcher-demo id="demo" lang="${this.lang}"></dbp-theme-switcher-demo> `; } } diff --git a/toolkit-showcase/src/dbp-tooltip-demo-activity.js b/toolkit-showcase/src/dbp-tooltip-demo-activity.js index 88d56187002263f300d0f6f38f047dfcaf81901c..27bbdca762e7e3f9aca6fadb9151c9372b193250 100644 --- a/toolkit-showcase/src/dbp-tooltip-demo-activity.js +++ b/toolkit-showcase/src/dbp-tooltip-demo-activity.js @@ -5,8 +5,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import readme from '@dbp-toolkit/tooltip/README.md'; -import * as demoStyles from "./styles"; -import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; +import * as demoStyles from './styles'; +import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element'; class DbpTooltipDemoActivity extends ScopedElementsMixin(AdapterLitElement) { constructor() { @@ -23,15 +23,14 @@ class DbpTooltipDemoActivity extends ScopedElementsMixin(AdapterLitElement) { static get properties() { return { ...super.properties, - lang: { type: String }, + lang: {type: String}, }; } connectedCallback() { super.connectedCallback(); - this.updateComplete.then(()=>{ - }); + this.updateComplete.then(() => {}); } static get styles() { @@ -41,22 +40,25 @@ class DbpTooltipDemoActivity extends ScopedElementsMixin(AdapterLitElement) { commonStyles.getGeneralCSS(), demoStyles.getDemoCSS(), css` - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } - #demo{ + #demo { display: block; padding-top: 50px; } - - ` + `, ]; } render() { return html` - ${unsafeHTML(readme)} - <dbp-tooltip-demo id="demo" lang="${this.lang}"></dbp-tooltip-demo> + ${unsafeHTML(readme)} + <dbp-tooltip-demo id="demo" lang="${this.lang}"></dbp-tooltip-demo> `; } } diff --git a/toolkit-showcase/src/styles.js b/toolkit-showcase/src/styles.js index 55d49382dd919e464ad646689568223b106a07e9..326d57e836ffbfdc9bb3056c0d6e98b6c07338f2 100644 --- a/toolkit-showcase/src/styles.js +++ b/toolkit-showcase/src/styles.js @@ -10,27 +10,35 @@ import highlightCSSPath from 'highlight.js/styles/github.css'; export function getDemoCSS() { // language=css return css` - @import url("${unsafeCSS(commonUtils.getAssetURL(highlightCSSPath))}"); + @import url('${unsafeCSS(commonUtils.getAssetURL(highlightCSSPath))}'); - h1.title {margin-bottom: 1em;} - div.container {margin-bottom: 1.5em;} - h1, h2, h3, h4 { + h1.title { + margin-bottom: 1em; + } + div.container { + margin-bottom: 1.5em; + } + h1, + h2, + h3, + h4 { margin-bottom: 20px; } - h2, h3, h4 { + h2, + h3, + h4 { margin: 40px 0 10px 0px; } - p{ - margin:10px 0; + p { + margin: 10px 0; } - ul{ + ul { margin-left: 14px; } - ul ul{ + ul ul { margin-left: 14px; } - a { transition: background-color 0.15s, color 0.15s; border-bottom: 1px solid rgba(0, 0, 0, 0.3); @@ -42,7 +50,7 @@ export function getDemoCSS() { } a:after { - content: "\\00a0\\00a0\\00a0"; + content: '\\00a0\\00a0\\00a0'; background-image: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3Ardf%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%228.6836mm%22%20width%3D%225.2043mm%22%20version%3D%221.1%22%20xmlns%3Acc%3D%22http%3A%2F%2Fcreativecommons.org%2Fns%23%22%20xmlns%3Adc%3D%22http%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%22%20viewBox%3D%220%200%2018.440707%2030.768605%22%3E%3Cg%20transform%3D%22translate(-382.21%20-336.98)%22%3E%3Cpath%20style%3D%22stroke-linejoin%3Around%3Bstroke%3A%23000%3Bstroke-linecap%3Around%3Bstroke-miterlimit%3A10%3Bstroke-width%3A2%3Bfill%3Anone%22%20d%3D%22m383.22%20366.74%2016.43-14.38-16.43-14.37%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E'); background-size: 73%; background-repeat: no-repeat; @@ -97,4 +105,4 @@ export function getDemoCSS() { padding: 0.25em 0.5em 0.25em; } `; -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 47ead6f173b3e6662b0ec7695a065149e09f32f7..3a4aaebba39e5d79438912b03ffc122b9b89af2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6744,6 +6744,11 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prettier@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== + process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"