cache and view improvements

This commit is contained in:
2026-03-30 16:28:20 +03:00
parent 7463fc6726
commit 4f0dbc7e91
9 changed files with 588 additions and 136 deletions
+144 -43
View File
@@ -1007,6 +1007,48 @@ function resolveFixedValue(string $key, $val, array $fixedLookup): string {
padding-right: 18px !important;
appearance: auto;
}
/* Select2 inside filter row */
.grid-filter-row .select2-container {
width: 100% !important;
min-width: 0;
flex: 1;
}
.grid-filter-row .select2-container .select2-selection--single {
height: 26px !important;
min-height: 26px !important;
display: flex !important;
align-items: center !important;
padding: 0 24px 0 6px;
font-size: 11px;
border: 1px solid #ced4da;
border-radius: 3px;
position: relative;
}
.grid-filter-row .select2-container .select2-selection__rendered {
line-height: 1 !important;
font-size: 11px;
padding: 0 !important;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.grid-filter-row .select2-container .select2-selection__arrow {
height: 26px !important;
position: absolute;
right: 2px;
top: 0;
}
.grid-filter-row .filter-wrap {
overflow: visible;
}
/* Hide our clear button when Select2 is active — Select2 has its own allowClear */
.filter-wrap:has(.select2-container) .filter-clear-btn {
display: none;
}
.grid-filter-row .grid-cell {
overflow: visible !important;
}
.filter-wrap {
display: flex;
align-items: center;
@@ -1747,15 +1789,14 @@ function resolveFixedValue(string $key, $val, array $fixedLookup): string {
</div>
<?php include('jsinclude.php'); ?>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function() {
// Resolve SceltaMultipla IDs → Valore (cells + filter selects)
// Resolve SceltaMultipla IDs → Valore in cells
(function() {
const sceltaEls = document.querySelectorAll('.scelta-value');
const sceltaFilters = document.querySelectorAll('select.scelta-filter');
const fieldIds = new Set();
sceltaEls.forEach(el => { if (el.dataset.fieldId) fieldIds.add(el.dataset.fieldId); });
sceltaFilters.forEach(el => { if (el.dataset.fieldId) fieldIds.add(el.dataset.fieldId); });
if (!fieldIds.size) return;
$.getJSON('get_customfield_values.php', { field_ids: [...fieldIds].join(',') }, function(data) {
@@ -1766,7 +1807,6 @@ function resolveFixedValue(string $key, $val, array $fixedLookup): string {
lookup[fid][v.IdCustomFieldsValue] = v.Valore;
});
}
// Resolve cell values
sceltaEls.forEach(el => {
const fid = el.dataset.fieldId;
const raw = (el.textContent || '').trim();
@@ -1774,55 +1814,116 @@ function resolveFixedValue(string $key, $val, array $fixedLookup): string {
el.textContent = lookup[fid][raw];
}
});
// Populate filter selects
sceltaFilters.forEach(sel => {
const fid = sel.dataset.fieldId;
if (!fid || !lookup[fid]) return;
const currentVal = sel.value;
// Sort by Valore
const sorted = Object.entries(lookup[fid]).sort((a, b) => a[1].localeCompare(b[1]));
sel.innerHTML = '<option value="">All</option>';
sorted.forEach(([id, label]) => {
const opt = document.createElement('option');
opt.value = id;
opt.textContent = label;
if (id === currentVal) opt.selected = true;
sel.appendChild(opt);
});
});
});
})();
// Load client names → resolve cells + populate filter selects
$.getJSON('get_clienti.php', function(data) {
const clients = data.value || [];
const map = {};
const sorted = [];
clients.forEach(c => {
const name = (c.Nominativo || '').trim();
map[c.IdCliente] = name;
sorted.push({ id: c.IdCliente, name: name });
// SceltaMultipla filter selects → AJAX Select2
document.querySelectorAll('select.scelta-filter').forEach(sel => {
const fieldId = sel.dataset.fieldId;
if (!fieldId) return;
const currentVal = sel.value;
if (currentVal) {
fetch('search_customfield_values.php?field_id=' + fieldId + '&id=' + encodeURIComponent(currentVal))
.then(r => r.json())
.then(json => {
const item = (json.results || [])[0];
if (item) sel.innerHTML = '<option value="">All</option><option value="' + item.id + '" selected>' + item.text + '</option>';
})
.catch(() => {});
}
$(sel).select2({
placeholder: 'All',
allowClear: true,
width: '100%',
minimumInputLength: 0,
ajax: {
url: 'search_customfield_values.php',
dataType: 'json',
delay: 150,
data: function(params) { return { field_id: fieldId, q: params.term || '', limit: 20 }; },
processResults: function(data) { return { results: data.results || [] }; },
cache: true
}
});
sorted.sort((a, b) => a.name.localeCompare(b.name));
});
// Resolve cell values
// SceltaMultipla filter → submit on change
$(document).on('change', 'select.scelta-filter', function() {
submitFilters();
});
// Resolve client names by unique IDs (lightweight)
(function() {
const ids = new Set();
document.querySelectorAll('.client-text').forEach(el => {
const id = el.getAttribute('data-client-id');
if (id && map[id]) el.textContent = map[id];
if (id) ids.add(id);
});
if (!ids.size) return;
// Populate client filter selects
document.querySelectorAll('select.client-filter').forEach(sel => {
const currentVal = sel.value;
sel.innerHTML = '<option value="">All</option>';
sorted.forEach(c => {
const opt = document.createElement('option');
opt.value = c.id;
opt.textContent = c.name;
if (String(c.id) === currentVal) opt.selected = true;
sel.appendChild(opt);
const promises = [...ids].map(id =>
fetch('search_clienti.php?id=' + encodeURIComponent(id))
.then(r => r.json())
.then(json => {
const item = (json.results || [])[0];
if (item) {
document.querySelectorAll(`.client-text[data-client-id="${id}"]`).forEach(el => {
el.textContent = item.text;
});
}
})
.catch(() => {})
);
Promise.all(promises);
})();
// Client filter selects → AJAX Select2
document.querySelectorAll('select.client-filter').forEach(sel => {
const currentVal = sel.value;
if (currentVal) {
fetch('search_clienti.php?id=' + encodeURIComponent(currentVal))
.then(r => r.json())
.then(json => {
const item = (json.results || [])[0];
if (item) {
sel.innerHTML = '<option value="">All</option><option value="' + item.id + '" selected>' + item.text + '</option>';
}
$(sel).select2({
placeholder: 'All',
allowClear: true,
width: '100%',
minimumInputLength: 0,
ajax: {
url: 'search_clienti.php',
dataType: 'json',
delay: 150,
data: function(params) { return { q: params.term || '', limit: 20 }; },
processResults: function(data) { return { results: data.results || [] }; },
cache: true
}
});
});
} else {
$(sel).select2({
placeholder: 'All',
allowClear: true,
width: '100%',
minimumInputLength: 0,
ajax: {
url: 'search_clienti.php',
dataType: 'json',
delay: 150,
data: function(params) { return { q: params.term || '', limit: 20 }; },
processResults: function(data) { return { results: data.results || [] }; },
cache: true
}
});
});
}
});
// Client filter select2 → submit on change
$(document).on('change', 'select.client-filter', function() {
submitFilters();
});
// Modal close handlers