Сортировка в таблицах и попытка приструнить генерацию превьюшек
All checks were successful
Deploy MES Core / deploy (push) Successful in 13s
All checks were successful
Deploy MES Core / deploy (push) Successful in 13s
This commit is contained in:
@@ -38,10 +38,114 @@
|
||||
localStorage.setItem('theme', newTheme);
|
||||
updateThemeIcon(newTheme);
|
||||
}
|
||||
|
||||
function sfParseDate(text) {
|
||||
const s = (text || '').trim();
|
||||
if (!s) return null;
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(s)) {
|
||||
const d = new Date(s + 'T00:00:00');
|
||||
return isNaN(d.getTime()) ? null : d;
|
||||
}
|
||||
const m = s.match(/^(\d{1,2})\.(\d{1,2})\.(\d{2}|\d{4})$/);
|
||||
if (m) {
|
||||
const dd = parseInt(m[1], 10);
|
||||
const mm = parseInt(m[2], 10) - 1;
|
||||
let yy = parseInt(m[3], 10);
|
||||
if (yy < 100) yy += 2000;
|
||||
const d = new Date(yy, mm, dd);
|
||||
return isNaN(d.getTime()) ? null : d;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function sfParseNumber(text) {
|
||||
const s = (text || '').toString().trim();
|
||||
if (!s) return null;
|
||||
const cleaned = s
|
||||
.replace(/\s+/g, '')
|
||||
.replace(/,/g, '.')
|
||||
.replace(/[^0-9.\-]/g, '');
|
||||
if (!cleaned || cleaned === '-' || cleaned === '.') return null;
|
||||
const n = parseFloat(cleaned);
|
||||
return isNaN(n) ? null : n;
|
||||
}
|
||||
|
||||
function sfMakeSortable(table) {
|
||||
const thead = table.querySelector('thead');
|
||||
const tbody = table.querySelector('tbody');
|
||||
if (!thead || !tbody) return;
|
||||
|
||||
const ths = Array.from(thead.querySelectorAll('th'));
|
||||
ths.forEach((th, idx) => {
|
||||
if ((th.getAttribute('data-sort') || '').toLowerCase() === 'false') return;
|
||||
|
||||
th.style.cursor = 'pointer';
|
||||
th.addEventListener('click', () => {
|
||||
const cur = table.getAttribute('data-sort-col');
|
||||
const sameCol = cur !== null && String(idx) === String(cur);
|
||||
const dir = sameCol && table.getAttribute('data-sort-dir') === 'asc' ? 'desc' : 'asc';
|
||||
table.setAttribute('data-sort-col', String(idx));
|
||||
table.setAttribute('data-sort-dir', dir);
|
||||
|
||||
const rows = Array.from(tbody.querySelectorAll('tr'));
|
||||
|
||||
// Комментарий: сортировка делается на клиенте. Мы просто переупорядочиваем строки в tbody.
|
||||
// Это работает для всех таблиц, где разметка уже готова, без переписывания вьюх.
|
||||
rows.sort((a, b) => {
|
||||
const aCell = a.children[idx];
|
||||
const bCell = b.children[idx];
|
||||
const aText = (aCell ? aCell.textContent : '').trim();
|
||||
const bText = (bCell ? bCell.textContent : '').trim();
|
||||
|
||||
const type = (th.getAttribute('data-sort-type') || '').toLowerCase();
|
||||
|
||||
if (type === 'number') {
|
||||
const an = sfParseNumber(aText);
|
||||
const bn = sfParseNumber(bText);
|
||||
if (an === null && bn === null) return 0;
|
||||
if (an === null) return dir === 'asc' ? 1 : -1;
|
||||
if (bn === null) return dir === 'asc' ? -1 : 1;
|
||||
return dir === 'asc' ? (an - bn) : (bn - an);
|
||||
}
|
||||
|
||||
if (type === 'date') {
|
||||
const ad = sfParseDate(aText);
|
||||
const bd = sfParseDate(bText);
|
||||
const at = ad ? ad.getTime() : null;
|
||||
const bt = bd ? bd.getTime() : null;
|
||||
if (at === null && bt === null) return 0;
|
||||
if (at === null) return dir === 'asc' ? 1 : -1;
|
||||
if (bt === null) return dir === 'asc' ? -1 : 1;
|
||||
return dir === 'asc' ? (at - bt) : (bt - at);
|
||||
}
|
||||
|
||||
// Попытка автоматически понять тип
|
||||
const an = sfParseNumber(aText);
|
||||
const bn = sfParseNumber(bText);
|
||||
if (an !== null && bn !== null) return dir === 'asc' ? (an - bn) : (bn - an);
|
||||
|
||||
const ad = sfParseDate(aText);
|
||||
const bd = sfParseDate(bText);
|
||||
if (ad && bd) return dir === 'asc' ? (ad.getTime() - bd.getTime()) : (bd.getTime() - ad.getTime());
|
||||
|
||||
const cmp = aText.localeCompare(bText, 'ru', { numeric: true, sensitivity: 'base' });
|
||||
return dir === 'asc' ? cmp : -cmp;
|
||||
});
|
||||
|
||||
const frag = document.createDocumentFragment();
|
||||
rows.forEach(r => frag.appendChild(r));
|
||||
tbody.appendChild(frag);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const savedTheme = localStorage.getItem('theme') || 'dark';
|
||||
document.documentElement.setAttribute('data-bs-theme', savedTheme);
|
||||
updateThemeIcon(savedTheme);
|
||||
|
||||
// Включаем сортировку для таблиц, которые явно помечены data-sortable="1".
|
||||
document.querySelectorAll('table[data-sortable="1"]').forEach(sfMakeSortable);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user