Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • advertisement
  • automagic
  • dbp-translation-component
  • demo
  • demo-file-handling
  • favorites-and-recent-files
  • icon-set-mapping
  • lit2
  • main
  • person-select-custom
  • port-i18next-parser
  • publish
  • remove-sentry
  • renovate/lock-file-maintenance
  • revert-6c632dc6
  • wc-part
  • wip-cleanup
17 results

Target

Select target project
  • 987FCF504483CBC8/toolkit
1 result
Select Git revision
  • advertisement
  • automagic
  • dbp-translation-component
  • demo
  • demo-file-handling
  • favorites-and-recent-files
  • icon-set-mapping
  • lit2
  • main
  • person-select-custom
  • port-i18next-parser
  • publish
  • remove-sentry
  • renovate/lock-file-maintenance
  • revert-6c632dc6
  • wc-part
  • wip-cleanup
17 results
Show changes
Commits on Source (27)
Showing
with 328 additions and 104 deletions
......@@ -12,10 +12,21 @@ npm i @dbp-toolkit/app-shell
## Usage
```html
<dbp-app-shell src="/example.topic.metadata.json"></dbp-app-shell>
<script type="module" src="node_modules/@dbp-toolkit/app-shell/dist/dbp-app-shell.js"></script>
<dbp-app-shell src="/example.topic.metadata.json"></dbp-app-shell>
```
Or directly via CDN:
```html
<script type="module" src="https://unpkg.com/@dbp-toolkit/app-shell@0.2.3/dist/dbp-app-shell.js"></script>
<dbp-app-shell src="/example.topic.metadata.json"></dbp-app-shell>
```
You need Keycloak and other parts to be in place to really make full use of the AppShell.
Best take a look on examples like [index.html](https://gitlab.tugraz.at/dbp/esign/signature/-/blob/master/examples/dbp-signature/index.html)
for more explanation.
## Attributes
- `lang` (optional, default: `de`): set to `de` or `en` for German or English
......@@ -47,6 +58,9 @@ The `details` attribute of the event is the language (possible values `en`, `de`
### Slots
You can give your slots a css class `slot-hidden` (which you have to define with `.slot-hidden { display: none; }`) to
hide the slots while the app shell is loading. This css class will then be removed from the slots by the app shell.
#### Unnamed slot
The unnamed slot will be removed when the application is loaded and can be filled with a loading-spinner.
......
{
"name": "@dbp-toolkit/app-shell",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/app-shell",
"version": "0.2.3",
"version": "0.2.4",
"main": "src/index.js",
"license": "LGPL-2.1-or-later",
"repository": {
......
......@@ -14,7 +14,7 @@ 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 {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element";
import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element";
const i18n = createI18nInstance();
......@@ -41,7 +41,7 @@ const importNotify = async (promise) => {
}
};
export class AppShell extends ScopedElementsMixin(AdapterLitElement) {
export class AppShell extends ScopedElementsMixin(DBPLitElement) {
constructor() {
super();
this.lang = i18n.language;
......@@ -848,9 +848,6 @@ export class AppShell extends ScopedElementsMixin(AdapterLitElement) {
const slot = this.shadowRoot.querySelector("slot:not([name])");
if (slot)
slot.remove();
// remove the "slot-hidden" class of elements in the html of injected slots to show them after the page was loaded
querySlotted(this.shadowRoot, '.slot-hidden').forEach((slot) => { slot.classList.remove("slot-hidden"); });
});
}
......
......@@ -15,6 +15,17 @@ npm i @dbp-toolkit/auth
<script type="module" src="node_modules/@dbp-toolkit/auth/dist/dbp-auth.js"></script>
```
Or directly via CDN:
```html
<dbp-auth-keycloak url="https://auth.tugraz.at/auth" realm="tugraz" client-id="some-id"></dbp-auth-keycloak>
<script type="module" src="https://unpkg.com/@dbp-toolkit/auth@0.2.2/dist/dbp-auth.js"></script>
```
You need Keycloak to be in place to make use of the auth component.
Best take a look on examples like [index.html](https://gitlab.tugraz.at/dbp/esign/signature/-/blob/master/examples/dbp-signature/index.html)
for more explanation.
### Attributes
- `lang` (optional, default: `de`): set to `de` or `en` for German or English
......
{
"name": "@dbp-toolkit/auth",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/auth",
"version": "0.2.2",
"version": "0.2.3",
"main": "src/index.js",
"license": "LGPL-2.1-or-later",
"repository": {
......
......@@ -13,6 +13,13 @@ npm i @dbp-toolkit/check-in-place-select
<script type="module" src="node_modules/@dbp-toolkit/check-in-place-select/dist/dbp-check-in-place-select.js"></script>
```
Or directly via CDN:
```html
<dbp-check-in-place-select></dbp-check-in-place-select>
<script type="module" src="https://unpkg.com/@dbp-toolkit/check-in-place-select@0.2.2/dist/dbp-check-in-place-select.js"></script>
```
## Attributes
- `lang` (optional, default: `de`): set to `de` or `en` for German or English
......
{
"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.2",
"version": "0.2.3",
"main": "src/index.js",
"license": "LGPL-2.1-or-later",
"repository": {
......
......@@ -11,7 +11,8 @@ npm i @dbp-toolkit/common
For valid icon names see: [LineIcons](https://lineicons.com/icons/)
```html
<dbp-icon color="orange" name="menu-down"></dbp-icon>
<script type="module" src="https://unpkg.com/@dbp-toolkit/common@0.2.8/dist/components.js"></script>
<dbp-icon style="color: red" name="menu-down"></dbp-icon>
```
### Exposed CSS variables
......@@ -25,6 +26,7 @@ Example CSS: `html { --dbp-override-icon-cloud: url(/icons/cloud.svg); }`
You can use this web component to show translated html.
```html
<script type="module" src="https://unpkg.com/@dbp-toolkit/common@0.2.8/dist/components.js"></script>
<dbp-translated subscribe="lang">
<div slot="de">
Dieser Text ist Deutsch und wird Englisch werden wenn man die Sprache auf Englisch stellt.
......
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);
commonUtils.defineCustomElement('dbp-icon', Icon);
commonUtils.defineCustomElement('dbp-button', Button);
commonUtils.defineCustomElement('dbp-loading-button', LoadingButton);
commonUtils.defineCustomElement('dbp-inline-notification', InlineNotification);
commonUtils.defineCustomElement('dbp-translated', Translated);
......@@ -13,16 +13,21 @@ export class DbpCommonDemo extends ScopedElementsMixin(LitElement) {
}
static get scopedElements() {
return {
let elements = {
'dbp-icon': Icon,
'dbp-mini-spinner': MiniSpinner,
'dbp-spinner': Spinner,
'dbp-button': Button,
'dbp-loading-button': LoadingButton,
'dbp-auth': customElements.get('dbp-auth'),
'dbp-inline-notification': InlineNotification,
'dbp-translated': Translated,
};
if (customElements.get('dbp-auth')) {
elements['dbp-auth'] = customElements.get('dbp-auth');
}
return elements;
}
static get properties() {
......
......@@ -4,4 +4,42 @@ export default class DBPLitElement extends AdapterLitElement {
_(selector) {
return this.shadowRoot === null ? this.querySelector(selector) : this.shadowRoot.querySelector(selector);
}
connectedCallback() {
this.updateComplete.then(() => {
// transform all named template slots in the light DOM to named div slots
this.transformTemplateSlots();
});
super.connectedCallback();
}
/**
* Transforms all named template slots in the light DOM to named div slots
*/
transformTemplateSlots() {
// query all named slots of the component
const slots = this.shadowRoot.querySelectorAll("slot[name]");
slots.forEach((slot) => {
const name = slot.name;
// search if there is a template with the name of the slot in the light DOM of the component
const templateElem = this.querySelector("template[slot=" + name + "]");
if (!templateElem) {
return;
}
// create a slot div container to put in the cloned template content
const divElem = document.createElement('div');
divElem.slot = name;
divElem.appendChild(templateElem.content.cloneNode(true));
// remove the old template with slot attribute
templateElem.remove();
// put the slot div container with the cloned template in the light DOM
this.appendChild(divElem);
});
}
}
{
"name": "@dbp-toolkit/common",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/common",
"version": "0.2.6",
"version": "0.2.8",
"module": "index.js",
"license": "LGPL-2.1-or-later",
"repository": {
......
......@@ -13,7 +13,7 @@ console.log("build: " + build);
export default (async () => {
return {
input: (build !='test') ? ['demo.js'] : glob.sync('test/**/*.js'),
input: (build !='test') ? ['demo.js', 'components.js'] : glob.sync('test/**/*.js'),
output: {
dir: 'dist',
entryFileNames: '[name].js',
......
......@@ -80,7 +80,15 @@ export const base64EncodeUnicode = (str) => {
*/
/**
*
* Same as customElements.define() but with some additional error handling.
*
* In case the same component (with the exact same implementation) is already
* defined then this will do nothing instead of erroring out.
*
* In case the browser doesn't support custom elements it will fill all those
* 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
......
# DataTableView Web Component
# Usage
## Usage
```html
<dbp-data-table-view></dbp-data-table-view>
<script type="module" src="node_modules/@dbp-toolkit/data-table-view/dist/dbp-data-table-view.js"></script>
```
# Attributes
Or directly via CDN:
```html
<dbp-data-table-view></dbp-data-table-view>
<script type="module" src="https://unpkg.com/@dbp-toolkit/data-table-view@0.2.2/dist/dbp-data-table-view.js"></script>
```
## Attributes
- `lang` (optional, default: `de`): set to `de` or `en` for German or English
- example `<dbp-data-table-view lang="de"></dbp-data-table-view>`
- `paging` (optional, required to let datatable do the paging of loaded rows)
......@@ -23,7 +32,8 @@
- example `<dbp-data-table-view default-order='[1,"asc"]'></pu-data-table-view>`
- example `<dbp-data-table-view default-order='[[0,"desc"],[2,"asc"]]'></pu-data-table-view>`
# Local development
## Local development
```bash
# get the source
git clone git@gitlab.tugraz.at:dbp/web-components/toolkit.git
......
{
"name": "@dbp-toolkit/data-table-view",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/data-table-view",
"version": "0.2.2",
"version": "0.2.3",
"main": "src/index.js",
"license": "LGPL-2.1-or-later",
"repository": {
......
......@@ -37,10 +37,18 @@ and the file sink dialog will open, so you are able to store the file again.
<script type="module" src="node_modules/@dbp-toolkit/file-handling/dist/dbp-file-sink.js"></script>
```
Or you can include the JS files directly via CDN:
```html
<script type="module" src="https://unpkg.com/@dbp-toolkit/file-handling@0.2.5/dist/dbp-file-source.js"></script>
<script type="module" src="https://unpkg.com/@dbp-toolkit/file-handling@0.2.5/dist/dbp-file-sink.js"></script>
<script type="module" src="https://unpkg.com/@dbp-toolkit/file-handling@0.2.5/dist/dbp-clipboard.js"></script>
```
## FileSource
This web component allows the selection of local files via file dialog or drag and drop and to select and download
files from a [Nextcloud](https://nextcloud.com/) instance.
files from a [Nextcloud](https://nextcloud.com/) instance or to a dbp-clipboard.
### Usage
......@@ -58,7 +66,7 @@ files from a [Nextcloud](https://nextcloud.com/) instance.
- example `<dbp-file-source allowed-mime-types='image/png,text/plain'></dbp-file-source>` ... PNGs or TXTs only
- example `<dbp-file-source allowed-mime-types='*/*'></dbp-file-source>` ... all file types (default)
- `enabled-targets` (optional, default: `local`): sets which sources are enabled
- you can use `local` and `nextcloud`
- you can use `local`, `nextcloud` and `clipboard`
- example `<dbp-file-source enabled-targets="local,nextcloud"></dbp-file-source>`
- `disabled` (optional): disable input control
- example `<dbp-file-source disabled></dbp-file-source>`
......@@ -115,7 +123,7 @@ This event is sent from nextcloudfilepicker and is send when files are picked an
## FileSink
This web component is able to receive files and present as them as ZIP file download or upload
files to a [Nextcloud](https://nextcloud.com/) instance.
files to a [Nextcloud](https://nextcloud.com/) instance or to a dbp-clipboard.
### Usage
......@@ -128,7 +136,7 @@ files to a [Nextcloud](https://nextcloud.com/) instance.
- `lang` (optional, default: `de`): set to `de` or `en` for German or English
- example `<dbp-file-sink lang="de"></dbp-file-sink>`
- `enabled-targets` (optional, default: `local`): sets which destination are enabled
- you can use `local` and `nextcloud`
- you can use `local`, `nextcloud` and `clipboard`
- example `<dbp-file-sink enabled-targets="local,nextcloud"></dbp-file-sink>`
- `filename` (optional, default: `files.zip`): sets a file name to use for downloading the zip file
- example `<dbp-file-sink filename="signed-documents.zip"></dbp-file-sink>`
......@@ -167,6 +175,67 @@ The component emits a `dbp-set-property` event for the attribute `initial-file-h
- `--dbp-override-image-nextcloud` is used to override the cloud image on the connection screen
- example CSS: `html { --dbp-override-image-nextcloud: url(/icons/nextcloud.svg); }`
## Clipboard
This web component is for a clipboard which saves the files to a provider. These files are available till the page is reload or the browser is closed.
### Depencencies
This web component can only used if a `dbp-provider` is around it.<br>
This web component depends on:
- `dbp-file-sink`
- `dbp-file-source`
### Usage
```html
<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name">
</dbp-clipboard>
```
### Attributes
- `clipboardFiles` is the object which should be subscribed to the provider to recieve and send the clipboard files
to the provider.
- exmaple `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name"></dbp-clipboard>`
- `lang` (optional, default: `de`): set to `de` or `en` for German or English
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" lang="de"></dbp-clipboard>`
- `enabled-targets` (optional, default: `local`): sets which destination are enabled
- you can use `local` and `nextcloud`
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" enabled-targets="local,nextcloud"></dbp-clipboard>`
- `allowed-mime-types` (optional): if set accepts only files matching mime types
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" allowed-mime-types='application/pdf'></dbp-clipboard>` ... PDFs only
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" allowed-mime-types='image/*'></dbp-clipboard>` ... images (of all sub types) only
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name"e allowed-mime-types='image/png,text/plain'></dbp-clipboard>` ... PNGs or TXTs only
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" allowed-mime-types='*/*'></dbp-clipboard>` ... all file types (default)
- `mode` (optional, default: `MODE_TABLE_ONLY`): the clipboard can used in three different contexts:
only showing the clipboard content, in the file-source context and in the file-sink context.
- you can use `MODE_TABLE_ONLY`, `MODE_FILE_SINK` or `MODE_FILE_SOURCE`
- example `<dbp-clipboard mode="MODE_TABLE_ONLY></dbp-clipboard>` ... only the table will shown
- example `<dbp-clipboard mode="MODE_FILE_SINK></dbp-clipboard>` ... the file-sink text and functionality is turned on
- example `<dbp-clipboard mode="MODE_FILE_SOURCE></dbp-clipboard>` ... the file-source text and functionality is turned on
- `filesToSave` this attribute is used by the `dbp-file-sink` to set the files in an array,
which should be saved to the clipboard to the `dbp-clipboard` web component
- `allow-nesting` (optional): is an boolean for demo purposes or special use cases.
It availables the clipboard in the file-source and file-sink in the clipboard itself.
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" allow-nesting></dbp-clipboard>` ... all file types (default)
- `nextcloud-auth-url` (optional): Nextcloud Auth Url to use with the Nextcloud file picker
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" nextcloud-auth-url="http://localhost:8081/index.php/apps/webapppassword"></dbp-clipboard>`
- `nextcloud-web-dav-url` also needs to be set for the Nextcloud file picker to be active
- `nextcloud-web-dav-url` (optional): Nextcloud WebDav Url to use with the Nextcloud file picker
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" nextcloud-web-dav-url="http://localhost:8081/remote.php/dav/files"></dbp-clipboard>`
- `nextcloud-auth-url` also needs to be set for the Nextcloud file picker to be active
- `nextcloud-file-url` (optional): Nextcloud File Url to use with the Nextcloud file picker
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" nextcloud-file-url="http://localhost:8081/apps/files/?dir="></dbp-clipboard>`
- `nextcloud-auth-info` (optional): Additional authentication information text that is shown in the Nextcloud file picker
- example `<dbp-clipboard subscribe="clipboard-files:clipboard-files-global-name" nextcloud-auth-info="You need special permissions for this function"></dbp-clipboard>`
### Exposed CSS variables
- `--dbp-override-image-nextcloud` is used to override the cloud image on the connection screen
- example CSS: `html { --dbp-override-image-nextcloud: url(/icons/nextcloud.svg); }`
## Local development
```bash
......
{
"name": "@dbp-toolkit/file-handling",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/file-handling",
"version": "0.2.4",
"version": "0.2.6",
"main": "src/index.js",
"license": "LGPL-2.1-or-later",
"repository": {
......
......@@ -34,8 +34,9 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
this.nextcloudWebDavURL = "";
this.nextcloudName = "";
this.nextcloudFileURL = "";
this.authInfo = '';
this.demo = false;
this.allowNesting = false;
// To avoid a cyclic dependency
import('./file-sink').then(({ FileSink }) => this.defineScopedElement('dbp-file-sink', FileSink));
......@@ -56,8 +57,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
lang: { type: String },
allowedMimeTypes: { type: String, attribute: 'allowed-mime-types' },
clipboardSelectBtnDisabled: { type: Boolean, attribute: true },
clipboardFiles: {type: Object, attribute: 'clipboard-files'},
filesToSave: {type: Array, attribute: 'files-to-save'},
clipboardFiles: {type: Object, attribute: 'clipboard-files' },
filesToSave: {type: Array, attribute: 'files-to-save' },
numberOfSelectedFiles: {type: Number, attribute: false },
enabledTargets: {type: String, attribute: 'enabled-targets'},
......@@ -65,10 +66,11 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
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'},
mode: {type: String, attribute: 'mode'},
demo: {type: Boolean, attribute: 'demo-clipboard' },
allowNesting: {type: Boolean, attribute: 'allow-nesting' },
};
}
......@@ -206,7 +208,9 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
that.generateClipboardTable();
});
if(!window.clipboardWarning) {
//Register only one beforeunload Event for the clipboard warning
if (!window.clipboardWarning) {
window.addEventListener('beforeunload', this._onReceiveBeforeUnload, false);
window.clipboardWarning = true;
}
......@@ -218,7 +222,6 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
//We doesn't want to deregister this event, because we want to use this event over activities
//window.removeEventListener('beforeunload', this._onReceiveBeforeUnload);
super.disconnectedCallback();
}
......@@ -237,6 +240,12 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
}
/**
* Checks if all files are already selected
* Returns true if all files are selected
*
* @return Boolean
*/
checkAllSelected() {
if (this.tabulatorTable) {
let maxSelected = this.tabulatorTable.getRows().filter(row => row.getData().type != 'directory' && this.checkFileType(row.getData(), this.allowedMimeTypes)).length;
......@@ -249,8 +258,13 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
/**
* Check mime type of a file, returns true if this.allowedMimeTypes contains the mime type of the file
*
* @param file
* @return Boolean
*/
checkFileType(file) {
// check if file is allowed
const [fileMainType, fileSubType] = file.type.split('/');
const mimeTypes = this.allowedMimeTypes.split(',');
......@@ -268,11 +282,14 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
return true;
}
/**
* If clipboard files and the tabulator table exists, then clear the table and sets the new data
*
*/
generateClipboardTable() {
if (this.clipboardFiles.files) {
let data = [];
for (let i = 0; i < this.clipboardFiles.files.length; i++){
for (let i = 0; i < this.clipboardFiles.files.length; i++) {
data[i] = {
name: this.clipboardFiles.files[i].name,
size: this.clipboardFiles.files[i].size,
......@@ -282,17 +299,20 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
};
}
if (this.tabulatorTable !== null){
if (this.tabulatorTable !== null) {
this.tabulatorTable.clearData();
this.tabulatorTable.setData(data);
}
}
}
/**
* Sends the files to a provider and throws a notification
*
* @param files
*/
async sendClipboardFiles(files) {
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();
......@@ -305,13 +325,10 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
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 });
this.dispatchEvent(event);
}
......@@ -320,7 +337,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
*
* @param event
*/
onReceiveBeforeUnload(event){
onReceiveBeforeUnload(event) {
// we don't need to stop if there are no signed files
if (this.clipboardFiles.files.length === 0) {
......@@ -328,8 +345,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
// we need to handle custom events ourselves
if(event.target && event.target.activeElement && event.target.activeElement.nodeName) {
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}),
......@@ -352,16 +368,21 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
}
saveFilesToClipboardEvent(ev)
/**
* Saves files from an event to the clipboard
*
* @param event
*/
saveFilesToClipboardEvent(event)
{
//save it
let data = {};
let files = [];
if (this.clipboardFiles && this.clipboardFiles.files.length !== 0) {
files = files.concat(this.clipboardFiles.files);
files = files.concat(ev.detail.file);
files = files.concat(event.detail.file);
} else {
files = files.concat(ev.detail.file);
files = files.concat(event.detail.file);
}
this.filesToSave = files;
if (files && files.length !== 0) {
......@@ -373,6 +394,10 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
}
/**
* Saves all files from this.filesToSave in clipboard and throws a notification
*
*/
saveFilesToClipboard()
{
//save it
......@@ -399,17 +424,25 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
}
finishedSaveFilesToClipboard(ev) {
/**
* Throws a finish notification with the count from the event.detail
*
* @param event
*/
finishedSaveFilesToClipboard(event) {
send({
"summary": i18n.t('clipboard.saved-files-title', {count: ev.detail.count}),
"body": i18n.t('clipboard.saved-files-body', {count: ev.detail.count}),
"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,
});
}
saveFilesFromClipboard() {
/**
* Open the file sink with clipboardfiles
*
*/
openFileSink() {
const fileSink = this._("#file-sink-clipboard");
if ( fileSink ) {
this._("#file-sink-clipboard").files = Object.create(this.tabulatorTable.getSelectedData().length > 0 ? this.tabulatorTable.getSelectedData() : this.clipboardFiles.files);
......@@ -417,26 +450,21 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
}
getClipboardFileList() {
let files = [];
for (let i = 0; i < this.clipboardFiles.files.length; i ++)
{
files[i] = html`<div class="clipboard-list"><strong>${this.clipboardFiles.files[i].name}</strong> ${humanFileSize(this.clipboardFiles.files[i].size)}</div>`;
}
return files;
}
/**
* Open Filesink for multiple files
* Open the file source with clipboardfiles
*
*/
async openClipboardFileSink() {
const fileSink = this._("#file-sink-clipboard");
if (fileSink) {
this._("#file-sink-clipboard").files = Object.create(this.clipboardFiles.files);
this._("#file-sink-clipboard").openDialog();
openFileSource() {
const fileSource = this._("#file-source-clipboard");
if (fileSource) {
this._("#file-source-clipboard").openDialog();
}
}
/**
* Delete all or only selected files from clipboard and throws a notification
*
*/
clearClipboard() {
if (this.tabulatorTable && this.tabulatorTable.getSelectedData().length > 0) {
let count = this.tabulatorTable.getSelectedData().length;
......@@ -465,18 +493,18 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
}
openFilesource() {
const fileSource = this._("#file-source");
if (fileSource) {
this._("#file-source").setAttribute("dialog-open", "");
}
}
/**
* Get the additional clipboard buttons
* If this.mode === MODE_FILE_SINK or MODE_FILE_SOURCE then there are only delete and save files buttons available
* Else there are the add, delete and save files buttons available
*
* @return html
*/
getAdditionalButtons() {
return html`
<div class="flex-container additional-button-container">
<div class="btn-flex-container-mobile">
<button @click="${() => { this.openFilesource(); }}"
<button @click="${() => { this.openFileSource(); }}"
class="button ${classMap({hidden: this.mode === MODE_FILE_SINK || this.mode === MODE_FILE_SOURCE})}" title="${i18n.t('clipboard.add-files')}">
<dbp-icon class="nav-icon" name="clipboard"></dbp-icon> ${i18n.t('clipboard.add-files-btn')}
</button>
......@@ -487,7 +515,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
</button>
</div>
<div class="btn-flex-container-mobile">
<button @click="${() => { this.saveFilesFromClipboard(); }}"
<button @click="${() => { this.openFileSink(); }}"
?disabled="${this.clipboardFiles.files.length === 0}"
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')}
......@@ -496,14 +524,15 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
</div>
<dbp-file-source
id="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}"
enabled-targets="${this.demo ? this.enabledTargets : this.enabledTargets.replace('clipboard', '')}"
nexcloud-auth-info="${this.nextcloudAuthInfo}"
enabled-targets="${this.allowNesting ? this.enabledTargets : this.enabledTargets.replace('clipboard', '')}"
decompress-zip
lang="${this.lang}"
text="${i18n.t('clipboard.upload-area-text')}"
......@@ -512,22 +541,28 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
@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-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.demo ? this.enabledTargets : this.enabledTargets.replace('clipboard', '')}"
enabled-targets="${this.allowNesting ? this.enabledTargets : this.enabledTargets.replace('clipboard', '')}"
show-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}"
lang="${this.lang}"
></dbp-file-sink>
`;
}
/**
* Get the clipboard sink html
*
* @return html
*/
getClipboardSink() {
const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css');
return html`
......@@ -560,7 +595,11 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
/**
* Get the clipboard source html
*
* @return html
*/
getClipboardSource() {
const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css');
return html`
......@@ -622,7 +661,6 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
font-style: italic;
padding-left: 2em;
margin-top: -1px;
/*line-height: 1.8;*/
margin-bottom: 1.2em;
}
......@@ -633,8 +671,9 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
}
.warning-icon{
margin-right: 20px;
margin-right: 10px;
font-size: 1.5rem;
margin-top: -23px;
}
.container{
......@@ -716,6 +755,10 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
.additional-button-container{
margin-top: 0.5rem;
}
.warning-container p{
margin-top: 0px;
}
@media only screen
and (orientation: portrait)
......@@ -746,6 +789,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
.checkmark{
height: 30px;
width:30px;
left: 0px;
top: 2px;
}
.button-container .checkmark::after{
......@@ -768,6 +813,12 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
margin-top: 5px;
}
.warning-icon{
margin-right: 10px;
font-size: 85px;
margin-top: -43px;
}
}
`;
......@@ -776,30 +827,27 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
render() {
const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css');
if (this.mode === MODE_FILE_SINK)
{
if (this.mode === MODE_FILE_SINK) {
return this.getClipboardSink();
}
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}">
<div class="table-wrapper">
<label class="button-container select-all-icon">
<input type="checkbox" id="select_all" name="select_all" value="select_all" @click="${() => {this.selectAllFiles();}}">
<span class="checkmark" title="${this.checkAllSelected() ? i18n.t("clipboard.select-nothing") : i18n.t("clipboard.select-all")}"></span>
</label>
<table id="clipboard-content-table" class="force-no-select"></table>
</div>
</div>
` ;
}
return html`
<div>
${this.getAdditionalButtons()}
<link rel="stylesheet" href="${tabulatorCss}">
<div class="table-wrapper">
<label class="button-container select-all-icon">
<input type="checkbox" id="select_all" name="select_all" value="select_all" @click="${() => {this.selectAllFiles();}}">
<span class="checkmark" title="${this.checkAllSelected() ? i18n.t("clipboard.select-nothing") : i18n.t("clipboard.select-all")}"></span>
</label>
<table id="clipboard-content-table" class="force-no-select"></table>
</div>
</div>
`;
}
}
\ No newline at end of file
......@@ -295,10 +295,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
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");
console.log("open nextcloud filepicker, no webdavclient");
//console.log("open nextcloud filepicker, no webdavclient");
} else {
this.loadDirectory(this.directoryPath, this.webDavClient);
console.log("load in nextcloud webcomponent");
//console.log("load in nextcloud webcomponent");
}
}
......@@ -476,6 +476,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
this.dispatchEvent(event);
this.loading = false;
this.statusText = "";
this.numberOfSelectedFiles = 0;
}).catch(error => {
console.error(error.message);
this.loading = false;
......@@ -490,6 +491,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
*/
sendDirectory(directory) {
this.tabulatorTable.deselectRow();
this.numberOfSelectedFiles = 0;
let path;
if (!directory[0]) {
......@@ -792,6 +794,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
}
closeDialog(e) {
this.numberOfSelectedFiles = 0;
MicroModal.close(this._('#modal-picker'));
}
......@@ -1462,6 +1465,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
.checkmark{
height: 30px;
width:30px;
left: 0px;
top: 2px;
}
}
......