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' + - '

Show column totals

\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('Object')); ?>
    - +
    @@ -223,7 +226,8 @@ class="sidebarPointer">t('Manual entry')); ?>
    t('Date')); ?>
    - +
    @@ -293,7 +297,8 @@ class="sidebarPointer">t('Data load')); ?>
    style="display: table-cell; width: 100%;">t('Object')); ?>
    + placeholder="t('single value or *')); ?>" autocomplete="off" + data-dropDownListIndex="0">
    @@ -418,9 +423,12 @@ class="sidebarPointer">t('Data load')); ?>
    @@ -601,4 +609,37 @@ class="icon-confirm share-pass-submit" + + + \ No newline at end of file