Skip to content
Snippets Groups Projects
Commit abed2f0d authored by Steinwender, Tamara's avatar Steinwender, Tamara
Browse files

Change clipboard filehandling

parent e3ce24fb
No related branches found
No related tags found
No related merge requests found
Pipeline #44059 failed
......@@ -17,7 +17,7 @@ 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'] : glob.sync('test/**/*.js'),
input: (build !== 'test') ? ['src/demo.js', 'src/dbp-file-source.js', 'src/dbp-file-sink.js', 'src/dbp-clipboard.js'] : glob.sync('test/**/*.js'),
output: {
dir: 'dist',
entryFileNames: '[name].js',
......
import {i18n} from './i18n';
import {css, html} from 'lit-element';
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 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 {FileSink} from "@dbp-toolkit/file-handling/src/file-sink";
import {FileSource} from "@dbp-toolkit/file-handling/src/file-source";
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";
export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
constructor() {
super();
this.lang = 'de';
this.allowedMimeTypes = '*/*';
this.clipboardFiles = {files: ''};
this.clipboardSelectBtnDisabled = true;
this.tabulatorTable = null;
this._onReceiveBeforeUnload = this.onReceiveBeforeUnload.bind(this);
this.filesToSave = [];
this.numberOfSelectedFiles = 0;
this.showAdditionalButtons = false;
this.enabledTargets = 'local';
this.nextcloudWebAppPasswordURL = "";
this.nextcloudWebDavURL = "";
this.nextcloudName = "";
this.nextcloudFileURL = "";
this.isFileSource = false;
this.isFileSink = false;
}
static get scopedElements() {
return {
'dbp-icon': Icon,
'dbp-file-sink': FileSink,
'dbp-file-source': FileSource,
};
}
static get properties() {
return {
...super.properties,
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'},
numberOfSelectedFiles: {type: Number, attribute: false },
showAdditionalButtons: {type: Boolean, attribute: 'show-additional-buttons' },
enabledTargets: {type: String, attribute: 'enabled-targets'},
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' },
isFileSource: {type: Boolean, attribute: 'file-sink' },
isFileSink: {type: Boolean, attribute: 'file-source' },
};
}
_(selector) {
return this.shadowRoot === null ? this.querySelector(selector) : this.shadowRoot.querySelector(selector);
}
update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
switch (propName) {
case "lang":
i18n.changeLanguage(this.lang);
break;
case "clipboardFiles":
this.generateClipboardTable();
break;
}
});
super.update(changedProperties);
}
connectedCallback() {
super.connectedCallback();
const that = this;
this.updateComplete.then(() => {
// see: http://tabulator.info/docs/4.7
this.tabulatorTable = new Tabulator(this._("#clipboard-content-table"), {
layout: "fitColumns",
selectable: true,
selectableRangeMode: "drag",
responsiveLayout: true,
resizableColumns: false,
placeholder: i18n.t("clipboard.no-data"),
columns: [
{
title: "",
field: "type",
align: "center",
headerSort: false,
width: 50,
responsive: 1,
formatter: (cell, formatterParams, onRendered) => {
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"),
responsive: 0,
widthGrow: 5,
minWidth: 150,
field: "name",
sorter: "alphanum",
formatter: (cell) => {
let data = cell.getRow().getData();
if (data.edit) {
cell.getElement().classList.add("fokus-edit");
}
return cell.getValue();
}
},
{
title: i18n.t("clipboard.file-size"),
responsive: 4,
widthGrow: 1,
minWidth: 50,
field: "size",
formatter: (cell, formatterParams, onRendered) => {
return cell.getRow().getData().type === "directory" ? "" : humanFileSize(cell.getValue());
}
},
{
title: i18n.t("clipboard.file-type"),
responsive: 2,
widthGrow: 1,
minWidth: 20,
field: "type",
formatter: (cell, formatterParams, onRendered) => {
if (typeof cell.getValue() === 'undefined') {
return "";
}
const [, fileSubType] = cell.getValue().split('/');
return fileSubType;
}
},
{
title: i18n.t("clipboard.file-mod"),
responsive: 3,
widthGrow: 1,
minWidth: 150,
field: "lastModified",
sorter: (a, b, aRow, bRow, column, dir, sorterParams) => {
const a_timestamp = Date.parse(a);
const b_timestamp = Date.parse(b);
return a_timestamp - b_timestamp;
},
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;
}
},
{title: "file", field: "file", visible: false}
],
initialSort: [
{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;
} else {
this._("#select_all").checked = false;
}
},
rowSelectionChanged: (data, rows) => {
if (this.tabulatorTable && this.tabulatorTable.getSelectedRows().length > 0) {
this.clipboardSelectBtnDisabled = false;
} else {
this.clipboardSelectBtnDisabled = true;
}
}
});
that.generateClipboardTable();
});
if(!window.clipboardWarning) {
window.addEventListener('beforeunload', this._onReceiveBeforeUnload, false);
window.clipboardWarning = true;
}
}
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();
}
/**
* Select or deselect all files from tabulator table
*
*/
selectAllFiles() {
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) {
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.numberOfSelectedFiles = maxSelected;
}
}
checkFileType(file) {
// check if file is allowed
const [fileMainType, fileSubType] = file.type.split('/');
const mimeTypes = this.allowedMimeTypes.split(',');
let deny = true;
mimeTypes.forEach((str) => {
const [mainType, subType] = str.split('/');
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}`);
return false;
}
return true;
}
generateClipboardTable() {
if (this.clipboardFiles.files) {
let data = [];
for (let i = 0; i < this.clipboardFiles.files.length; i++){
data[i] = {
name: this.clipboardFiles.files[i].name,
size: this.clipboardFiles.files[i].size,
type: this.clipboardFiles.files[i].type,
lastModified: this.clipboardFiles.files[i].lastModified,
file: this.clipboardFiles.files[i]
};
}
if (this.tabulatorTable !== null){
this.tabulatorTable.clearData();
this.tabulatorTable.setData(data);
}
}
}
async sendClipboardFiles(files) {
for(let i = 0; i < files.length; i ++)
{
await this.sendFileEvent(files[i].file);
}
this.tabulatorTable.deselectRow();
}
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);
}
/**
* Decides if the "beforeunload" event needs to be canceled
*
* @param event
*/
onReceiveBeforeUnload(event){
// we don't need to stop if there are no signed files
if (this.clipboardFiles.files.length === 0) {
return;
}
// 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,
});
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");
// don't stop the page leave if the user wants to leave
if (result) {
return;
}
}
// Cancel the event as stated by the standard
event.preventDefault();
// Chrome requires returnValue to be set
event.returnValue = '';
}
}
saveFilesToClipboard(ev)
{
//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);
} else {
files = files.concat(ev.detail.file);
}
this.filesToSave = files;
if (files && files.length !== 0) {
data = {"files": files};
this.sendSetPropertyEvent('clipboard-files', data);
const event = new CustomEvent("dbp-clipboard-file-picker-file-uploaded",
{ bubbles: true, composed: true });
this.dispatchEvent(event);
}
}
finishedSaveFilesToClipboard(ev) {
send({
"summary": i18n.t('clipboard.saved-files-title', {count: ev.detail.count}),
"body": i18n.t('clipboard.saved-files-body', {count: ev.detail.count}),
"type": "success",
"timeout": 5,
});
}
saveFilesFromClipboard() {
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);
this._("#file-sink-clipboard").openDialog();
}
}
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
*/
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();
}
}
clearClipboard() {
if(this.tabulatorTable && this.tabulatorTable.getSelectedData().length > 0) {
let data = {"files": this.clipboardFiles.files};
this.tabulatorTable.getSelectedData().forEach(toRemove =>
data.files = data.files.filter(file => toRemove.name !== file.name)
);
this.sendSetPropertyEvent('clipboard-files', data);
const event = new CustomEvent("dbp-clipboard-file-picker-file-uploaded",
{ bubbles: true, composed: true });
this.dispatchEvent(event);
send({
"summary": i18n.t('clipboard.clear-count-clipboard-title', {count: this.tabulatorTable.getSelectedData().length}),
"body": i18n.t('clipboard.clear-count-clipboard-body', {count: this.tabulatorTable.getSelectedData().length}),
"type": "success",
"timeout": 5,
});
this.numberOfSelectedFiles = 0;
} else {
let data = {"files": []};
this.sendSetPropertyEvent('clipboard-files', data);
const event = new CustomEvent("dbp-clipboard-file-picker-file-uploaded",
{ bubbles: true, composed: true });
this.dispatchEvent(event);
send({
"summary": i18n.t('clipboard.clear-clipboard-title'),
"body": i18n.t('clipboard.clear-clipboard-body'),
"type": "success",
"timeout": 5,
});
}
}
openFilesink() {
const fileSink = this._("#file-source");
if (fileSink) {
this._("#file-source").setAttribute("dialog-open", "");
}
}
getAdditionalButtons() {
return html`
<div class="flex-container">
<div class="btn-flex-container-mobile">
<button @click="${() => { this.openFilesink(); }}"
class="button" title="${i18n.t('clipboard.add-files')}">
<dbp-icon class="nav-icon" name="clipboard"></dbp-icon> ${i18n.t('clipboard.add-files-btn')}
</button>
<button @click="${() => { this.clearClipboard(); }}"
class="button" title="${(this.numberOfSelectedFiles > 0) ? i18n.t('clipboard.remove-count', {count: this.numberOfSelectedFiles}) : i18n.t('clipboard.remove-all')}"
?disabled="${this.clipboardFiles.files.length === 0}">
${(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 @click="${() => { this.saveFilesFromClipboard(); }}"
?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')}
</button>
</div>
</div>
<dbp-file-source
id="file-source"
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.enabledTargets}"
decompress-zip
lang="${this.lang}"
text="${i18n.t('clipboard.upload-area-text')}"
button-label="${i18n.t('clipboard.upload-button-label')}"
show-clipboard
@dbp-file-source-file-selected="${this.saveFilesToClipboard}"
@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.enabledTargets}"
show-clipboard
nextcloud-auth-url="${this.nextcloudWebAppPasswordURL}"
nextcloud-web-dav-url="${this.nextcloudWebDavURL}"
nextcloud-name="${this.nextcloudName}"
nextcloud-file-url="${this.nextcloudFileURL}"
lang="${this.lang}"
subscribe="nextcloud-file-url:nextcloud-file-url"
></dbp-file-sink>
`;
}
getClipboardSink() {
return html`
//todo header + table
<!-- Clipboard Footer -->
<div class="clipboard-footer">
<button class="button select-button is-primary" ?disabled="${this.clipboardSelectBtnDisabled}"
@click="${() => {this.sendClipboardFiles(this.tabulatorTable.getSelectedData());}}">${i18n.t('nextcloud-file-picker.select-files')}
</button>
</div>
`;
}
getClipboardSource() {
return html`
//todo header + table
<!-- Clipboard Footer -->
<div class="clipboard-footer">
<button class="button select-button is-primary" ?disabled="${this.clipboardSelectBtnDisabled}"
@click="${() => {this.sendClipboardFiles(this.tabulatorTable.getSelectedData());}}">${i18n.t('nextcloud-file-picker.select-files')}
</button>
</div>
`;
}
static get styles() {
// language=css
return css`
${commonStyles.getThemeCSS()}
${commonStyles.getGeneralCSS(false)}
${commonStyles.getButtonCSS()}
${commonStyles.getTextUtilities()}
${commonStyles.getModalDialogCSS()}
${commonStyles.getRadioAndCheckboxCss()}
${fileHandlingStyles.getFileHandlingCss()}
a {
border-bottom: 1px solid rgba(0,0,0,0.3);
padding: 0;
}
a:hover {
color: #fff;
background-color: #000;
}
h2:first-child {
margin-top: 0;
margin-bottom: 0px;
}
.subheadline{
font-style: italic;
padding-left: 2em;
margin-top: -1px;
/*line-height: 1.8;*/
margin-bottom: 1.2em;
}
.warning-container{
display: flex;
flex-direction: inherit;
align-items: center;
margin-bottom: 1.5rem;
}
.warning-icon{
margin-right: 20px;
font-size: 1.5rem;
}
.container{
margin-top: 2rem;
}
.flex-container{
margin-bottom: 5px;
}
.select-btn-wrapper{
float: right;
}
.init{
margin: 0px;
}
.flex-container{
display: flex;
justify-content: space-between;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder span{
margin: initial;
}
.checkmark{
height: 20px;
width:20px;
}
.button-container .checkmark::after{
left: 8px;
top: 3px;
width: 4px;
height: 11px;
}
.table-wrapper{
position: relative;
}
.select-all-icon{
position: absolute;
top: 17px;
left: 10px;
z-index: 100;
height: 40px;
}
.clipboard-footer {
align-self: end;
}
@media only screen
and (orientation: portrait)
and (max-device-width: 765px) {
.flex-container{
justify-content: space-between;
display: flex;
}
.btn-flex-container-mobile{
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
.select-btn-wrapper{
width: 100%;
display: flex;
justify-content: end;
float: none;
}
.flex-container{
display: block;
}
.checkmark{
height: 30px;
width:30px;
}
.button-container .checkmark::after{
left: 11px;
top: 4px;
width: 8px;
height: 15px;
}
.select-all-icon{
top: 10px;
left: 10px;
}
.btn-flex-container-mobile{
flex-direction: column;
}
.btn-flex-container-mobile button:nth-child(2){
margin-top: 5px;
}
.clipboard-footer {
padding-top: 10px;
align-self: center;
}
}
`;
}
render() {
const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css');
let additionalButtons = this.showAdditionalButtons ? this.getAdditionalButtons() : "";
if (this.isFileSink)
return this.getClipboardSink();
if (this.isFileSource)
return this.getClipboardSource()
return html`
<div class="container">
${additionalButtons}
<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"></span>
</label>
<table id="clipboard-content-table" class="force-no-select"></table>
</div>
</div>
`;
}
}
\ No newline at end of file
import * as commonUtils from "@dbp-toolkit/common/utils";
import {Clipboard} from './clipboard';
commonUtils.defineCustomElement('dbp-clipboard', Clipboard);
......@@ -11,7 +11,7 @@ import FileSaver from 'file-saver';
import MicroModal from "./micromodal.es";
import * as fileHandlingStyles from './styles';
import { send } from '@dbp-toolkit/common/notification';
import {FileHandlingClipboard} from "./dbp-file-handling-clipboard";
import {Clipboard} from "@dbp-toolkit/file-handling/src/clipboard";
/**
......@@ -46,7 +46,7 @@ export class FileSink extends ScopedElementsMixin(DBPLitElement) {
'dbp-icon': Icon,
'dbp-mini-spinner': MiniSpinner,
'dbp-nextcloud-file-picker': NextcloudFilePicker,
'dbp-clipboard': FileHandlingClipboard,
'dbp-clipboard': Clipboard,
};
}
......@@ -239,6 +239,7 @@ export class FileSink extends ScopedElementsMixin(DBPLitElement) {
<dbp-clipboard
id="clipboard-file-sink"
subscribe="clipboard-files:clipboard-files"
file-sink
lang="${this.lang}"
auth-url="${this.nextcloudAuthUrl}"
allowed-mime-types="${this.allowedMimeTypes}"
......
......@@ -10,7 +10,7 @@ import {NextcloudFilePicker} from "./dbp-nextcloud-file-picker";
import {classMap} from 'lit-html/directives/class-map.js';
import MicroModal from './micromodal.es';
import * as fileHandlingStyles from './styles';
import {FileHandlingClipboard} from "./dbp-file-handling-clipboard";
import {Clipboard} from "@dbp-toolkit/file-handling/src/clipboard";
function mimeTypesToAccept(mimeTypes) {
// Some operating systems can't handle mime types and
......@@ -64,7 +64,7 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
'dbp-icon': Icon,
'dbp-mini-spinner': MiniSpinner,
'dbp-nextcloud-file-picker': NextcloudFilePicker,
'dbp-clipboard': FileHandlingClipboard,
'dbp-clipboard': Clipboard,
};
}
......@@ -428,7 +428,7 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
return html`
<dbp-clipboard
id="clipboard-file-picker"
clipboard-source
file-source
subscribe="clipboard-files:clipboard-files"
lang="${this.lang}"
auth-url="${this.nextcloudAuthUrl}"
......
......@@ -106,6 +106,41 @@
"save-files-from-clipboard_plurafile-sinkl": "{{count}} Dateien aus der Zwischenablage speichern",
"save-from-clipboard": "Aktuellen Inhalt aus der Zwischenablage speichern:",
"save-from-clipboard-btn": "Zwischenablage sichern",
"save-to-clipboard-title": "Dateien in der Zwischenablage ablegen"
"save-to-clipboard-title": "Dateien in der Zwischenablage ablegen",
"add-files": "Dateien der Zwischenablage hinzufügen",
"add-files-btn": "Dateien hinzufügen",
"remove-all": "Alle Dateien aus der Zwischenablage entfernen.",
"remove-all-btn": "Alle 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 speichern",
"save-all-btn": "Alle sichern",
"upload-area-text": "Sie können in diesem Bereich Dokumente mit einer Maximalgröße von bis zu 32MB pro Dokument per Drag & Drop oder per Direktauswahl hochladen.",
"upload-button-label": "Dateien auswählen",
"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.",
"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.",
"save-count-btn": "Datei speichern",
"save-count-btn_plural": "{{count}} Dateien speichern",
"save-count": "Eine Datei aus der Zwischenablage speichern",
"save-count_plural": "{{count}} Dateien aus der Zwischenablage speichern",
"file-name": "Name",
"file-size": "Größe",
"file-type": "Art",
"file-mod": "Geändert",
"select-all": "Alle auswählen",
"select-all-title": "Alle verfügbaren Dateien in diesem Ordner auswählen",
"select-nothing": "Nichts auswählen",
"select-nothing-title": "Alle gewählten Dateien nicht mehr selektieren",
"no-data": "Keine Dateien vorhanden"
}
}
......@@ -106,6 +106,41 @@
"save-files-from-clipboard_plural": "Save {{count}} files from the clipboard",
"save-from-clipboard": "Save the current content from the clipboard:",
"save-from-clipboard-btn": "Save the clipboard",
"save-to-clipboard-title": "Cached files in the clipboard "
"save-to-clipboard-title": "Cached files in the 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",
"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",
"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.",
"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.",
"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",
"select-all": "Alle auswählen",
"select-all-title": "Alle verfügbaren Dateien in diesem Ordner auswählen",
"select-nothing": "Nichts auswählen",
"select-nothing-title": "Alle gewählten Dateien nicht mehr selektieren",
"no-data": "There are no files"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment