diff --git a/css/style.css b/css/style.css
index 1c82f68f..7dbb9bf4 100644
--- a/css/style.css
+++ b/css/style.css
@@ -495,6 +495,11 @@ table.dataTable tbody tr {
filter: var(--background-invert-if-dark);
}
+.icon-analytics-tableOptions {
+ background-image: url(../img/tableOptions.svg);
+ filter: var(--background-invert-if-dark);
+}
+
.filterVisualizationItem {
background-color: var(--color-background-dark);
padding: 5px;
@@ -709,7 +714,8 @@ table.dataTable tbody tr {
grid-template-areas:
"dummy columns"
"rows measures"
- "dummy2 totals";
+ "dummy2 totals"
+ "hidden hidden";
grid-template-columns: 1fr 2fr;
grid-template-rows: auto; /* Define the height for rows and measures */
gap: 10px;
diff --git a/img/tableOptions.svg b/img/tableOptions.svg
new file mode 100644
index 00000000..34081cc0
--- /dev/null
+++ b/img/tableOptions.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/js/filter.js b/js/filter.js
index 497fcc56..b7289b88 100644
--- a/js/filter.js
+++ b/js/filter.js
@@ -293,54 +293,25 @@ OCA.Analytics.Filter = {
OCA.Analytics.Filter.processTableOptionsDialog
);
-/* // Total row setting
- (tableOptions.footer ? option1 : option2).selected = true;
-*/
-
- let layoutRaw = '
\n' +
- '
' +
- '
' +
- '
\n' +
- '
Rows
\n' +
- '
\n' +
- '
\n' +
- '
\n' +
- '
Columns
\n' +
- '
\n' +
- '
\n' +
- '
\n' +
- '
Measures
\n' +
- '
\n' +
- '
\n' +
- '
\n' +
- '
';
-
- let parser = new DOMParser();
- let layout = parser.parseFromString(layoutRaw, 'text/html');
- let container = layout.querySelector('.tableOptionsLayout');
-
- // add the final content to the modal
- let content = document.createDocumentFragment();
- content.appendChild(container.cloneNode(true)); // Clone the container with event listeners
+ // clone the DOM template
+ let container = document.getElementById('templateTableOptions').content;
+ container = document.importNode(container, true);
// Attach event listeners programmatically
- content.querySelectorAll('.columnSection').forEach(section => {
+ container.querySelectorAll('.columnSection').forEach(section => {
section.addEventListener('drop', OCA.Analytics.Filter.Drag.drop);
section.addEventListener('dragover', OCA.Analytics.Filter.Drag.allowDrop);
});
+ if (tableOptions && tableOptions.footer) {
+ container.querySelector('input[name="totalOption"][value="true"]').checked = true;
+ } else {
+ container.querySelector('input[name="totalOption"][value="false"]').checked = true;
+ }
+
OCA.Analytics.Notification.htmlDialogUpdate(
- content,
- t('analytics', 'The table can be customized by selecting the rows and columns.
If a classic list view is required, all fields need to be placed in the rows section.')
+ container,
+ t('analytics', 'The table can be customized by positioning the rows and columns.
If a classic list view is required, all fields need to be placed in the rows section.')
);
OCA.Analytics.Filter.Drag.initialize();
@@ -350,27 +321,23 @@ OCA.Analytics.Filter = {
let tableOptions;
try {
tableOptions = JSON.parse(OCA.Analytics.currentReportData.options.tableoptions);
+ if (tableOptions === null) {
+ tableOptions = {};
+ }
} catch (e) {
- tableOptions = [];
+ tableOptions = {};
}
- let tableOptionTotalRow;
- let radios = document.getElementsByName('totalOption');
- for (let i = 0; i < radios.length; i++) {
- if (radios[i].checked) {
- tableOptionTotalRow = radios[i].value;
- }
- }
+ const selectedRadio = document.querySelector('input[name="totalOption"]:checked');
+ const tableOptionTotalRow = selectedRadio ? selectedRadio.value : null;
- //let tableOptionTotalRow = document.getElementById('tableOptionTotalRow').value;
if (tableOptionTotalRow === 'true') {
tableOptions.footer = true;
- } else {
+ } else if (tableOptions) {
delete tableOptions.footer;
}
let layout = {};
-
document.querySelectorAll('.columnSection').forEach(function (section) {
var sectionId = section.id;
// Initialize the layout[sectionId] as an empty array if undefined
@@ -384,7 +351,16 @@ OCA.Analytics.Filter = {
}
});
- tableOptions.layout = layout;
+ const isSequential = (arr) => arr.every((val, i, array) => i === 0 || (val === array[i - 1] + 1));
+ if (layout.columns.length === 0 && layout.measures.length === 0 && layout.hidden.length === 0) {
+ if (!isSequential(layout.rows)) {
+ tableOptions.layout = layout;
+ } else if (tableOptions && tableOptions.layout) {
+ delete tableOptions.layout;
+ }
+ } else {
+ tableOptions.layout = layout;
+ }
OCA.Analytics.currentReportData.options.tableoptions = JSON.stringify(tableOptions);
OCA.Analytics.unsavedFilters = true;
@@ -735,7 +711,7 @@ OCA.Analytics.Filter.Drag = {
const createPlaceholder = () => {
let placeholderDiv = document.createElement('div');
placeholderDiv.className = 'dragAndDropPlaceholder';
- placeholderDiv.textContent = 'Please drag content here';
+ placeholderDiv.textContent = t('analytics', 'Drag fields here');
return placeholderDiv;
};
diff --git a/templates/part.menu.php b/templates/part.menu.php
index d0ac8fbd..bbe6bceb 100644
--- a/templates/part.menu.php
+++ b/templates/part.menu.php
@@ -28,7 +28,7 @@
diff --git a/templates/part.templates.php b/templates/part.templates.php
index c155009f..85c84ea7 100644
--- a/templates/part.templates.php
+++ b/templates/part.templates.php
@@ -106,11 +106,13 @@ class="sidebarPointer">t('Visualization')); ?>
p($l->t('Bar')); ?>
-
-
-
@@ -215,7 +217,8 @@ class="sidebarPointer">t('Manual entry')); ?>
t('Date')); ?>
-
+
style="display: table-cell; width: 100%;">t('Object')); ?>
+ placeholder="t('single value or *')); ?>" autocomplete="off"
+ data-dropDownListIndex="0">
-
-
-
+
+
+
@@ -601,4 +609,37 @@ class="icon-confirm share-pass-submit"
+
+
+
+
+
+
+
+
+
+
+
+
t('Not required')); ?>
+
+
+
\ No newline at end of file