Skip to content
Snippets Groups Projects
Verified Commit 89442aba authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat: copy and copy all for datatable

parent 5aab2c6e
No related branches found
No related tags found
No related merge requests found
...@@ -106,6 +106,12 @@ const gridHeadersElementSymbol = Symbol("gridHeadersElement"); ...@@ -106,6 +106,12 @@ const gridHeadersElementSymbol = Symbol("gridHeadersElement");
*/ */
const columnBarElementSymbol = Symbol("columnBarElement"); const columnBarElementSymbol = Symbol("columnBarElement");
/**
* @private
* @type {symbol}
*/
const copyAllElementSymbol = Symbol("copyAllElement");
/** /**
* @private * @private
* @type {symbol} * @type {symbol}
...@@ -174,6 +180,7 @@ class DataTable extends CustomElement { ...@@ -174,6 +180,7 @@ class DataTable extends CustomElement {
* @property {boolean} features.settings Settings feature * @property {boolean} features.settings Settings feature
* @property {boolean} features.footer Footer feature * @property {boolean} features.footer Footer feature
* @property {boolean} features.autoInit Auto init feature (init datasource automatically) * @property {boolean} features.autoInit Auto init feature (init datasource automatically)
* @property {boolean} features.doubleClickCopyToClipboard Double click copy to clipboard feature
* @property {Object} templateMapping Template mapping * @property {Object} templateMapping Template mapping
* @property {string} templateMapping.row-key Row key * @property {string} templateMapping.row-key Row key
* @property {string} templateMapping.filter-id Filter id * @property {string} templateMapping.filter-id Filter id
...@@ -205,6 +212,7 @@ class DataTable extends CustomElement { ...@@ -205,6 +212,7 @@ class DataTable extends CustomElement {
labels: { labels: {
theListContainsNoEntries: "The list contains no entries", theListContainsNoEntries: "The list contains no entries",
copyAll: "Copy all",
}, },
classes: { classes: {
...@@ -217,6 +225,15 @@ class DataTable extends CustomElement { ...@@ -217,6 +225,15 @@ class DataTable extends CustomElement {
settings: true, settings: true,
footer: true, footer: true,
autoInit: true, autoInit: true,
doubleClickCopyToClipboard: true,
copyAll: true,
},
copy: {
delimiter: ";",
quoteOpen: '"',
quoteClose: '"',
rowBreak: "\n",
}, },
templateMapping: { templateMapping: {
...@@ -661,6 +678,11 @@ function updateConfigColumnBar() { ...@@ -661,6 +678,11 @@ function updateConfigColumnBar() {
function initEventHandler() { function initEventHandler() {
const self = this; const self = this;
const quoteOpenChar = this.getOption("copy.quoteOpen");
const quoteCloseChar = this.getOption("copy.quoteClose");
const delimiterChar = this.getOption("copy.delimiter");
const rowBreak = this.getOption("copy.rowBreak");
self[columnBarElementSymbol].attachObserver( self[columnBarElementSymbol].attachObserver(
new Observer((e) => { new Observer((e) => {
updateHeaderFromColumnBar.call(self); updateHeaderFromColumnBar.call(self);
...@@ -696,6 +718,113 @@ function initEventHandler() { ...@@ -696,6 +718,113 @@ function initEventHandler() {
}); });
} }
}); });
const eventHandlerDoubleClickCopyToClipboard = (event) => {
const element = findTargetElementFromEvent(event, "data-monster-head");
if (element) {
let text = "";
if (event.shiftKey) {
const index = element.getAttribute("data-monster-insert-reference");
if (index) {
const cols = self.getGridElements(`[data-monster-insert-reference="${index}"]`);
const colTexts = []
for (let i = 0; i < cols.length; i++) {
const col = cols[i];
if (col.querySelector("monster-button-bar") || col.querySelector("monster-button")) {
continue;
}
if (col.textContent) {
colTexts.push(quoteOpenChar+col.textContent.trim()+quoteCloseChar);
}
}
text = colTexts.join(delimiterChar);
}
} else {
if (element.querySelector("monster-button-bar") || element.querySelector("monster-button")) {
return;
}
text = element.textContent.trim();
}
if (getWindow().navigator.clipboard && text) {
getWindow().navigator.clipboard.writeText(text).then(
() => {
},
(err) => {
}
);
}
}
}
if (self.getOption("features.doubleClickCopyToClipboard")) {
self[gridElementSymbol].addEventListener("dblclick", eventHandlerDoubleClickCopyToClipboard);
}
if (self.getOption("features.copyAll") && this[copyAllElementSymbol]) {
this[copyAllElementSymbol].addEventListener("click", (event) => {
event.preventDefault();
const table = [];
let currentRow = [];
let currentIndex= null;
const cols = self.getGridElements(`[data-monster-insert-reference]`);
for (let i = 0; i < cols.length; i++) {
const col = cols[i];
const index = col.getAttribute("data-monster-insert-reference");
if (currentIndex !== index) {
if (currentRow.length > 0) {
table.push(currentRow);
}
currentRow = [];
currentIndex = index;
}
if (col.querySelector("monster-button-bar") || col.querySelector("monster-button")) {
continue;
}
if (col.textContent) {
currentRow.push(quoteOpenChar+col.textContent.trim()+quoteCloseChar);
}
}
if(table.length > 0) {
const text = table.map(row => row.join(delimiterChar)).join(rowBreak);
if (getWindow().navigator.clipboard && text) {
getWindow().navigator.clipboard.writeText(text).then(
() => {
},
(err) => {
}
);
}
}
});
}
} }
/** /**
...@@ -952,6 +1081,10 @@ function initControlReferences() { ...@@ -952,6 +1081,10 @@ function initControlReferences() {
this[columnBarElementSymbol] = this[columnBarElementSymbol] =
this.shadowRoot.querySelector("monster-column-bar"); this.shadowRoot.querySelector("monster-column-bar");
this[copyAllElementSymbol] = this.shadowRoot.querySelector(
"[data-monster-role=copy-all]",
);
return this; return this;
} }
...@@ -1018,6 +1151,7 @@ function getTemplate() { ...@@ -1018,6 +1151,7 @@ function getTemplate() {
<slot name="filter"></slot> <slot name="filter"></slot>
</div> </div>
<div class="bar"> <div class="bar">
<a href="#" data-monster-attributes="class path:features.copyAll | ?::hidden" data-monster-role="copy-all" data-monster-replace="path:locale.copyAll">Copy all</a>
<monster-column-bar <monster-column-bar
data-monster-attributes="class path:features.settings | ?::hidden"></monster-column-bar> data-monster-attributes="class path:features.settings | ?::hidden"></monster-column-bar>
<slot name="bar"></slot> <slot name="bar"></slot>
......
...@@ -230,6 +230,26 @@ ...@@ -230,6 +230,26 @@
} }
& a[data-monster-role="copy-all"] {
display: flex;
align-items: center;
color: var(--monster-color-primary-1);
background: none;
white-space: nowrap;
&:after {
content: "";
display: block;
width: 20px;
height: 16px;
margin: 2px 3px 0 5px;
padding-top: 4px;
background-color: var(--monster-color-primary-1);
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1z'/%3E%3Cpath d='M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0z'/%3E%3C/svg%3E");
mask-size: cover;
}
}
.filter { .filter {
margin: 0 0 20px 0; margin: 0 0 20px 0;
} }
......
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment