Implement direct days-until-start column filter

This commit is contained in:
2026-02-23 20:48:55 +01:00
parent 6a54f3652a
commit 85f9de74bf
2 changed files with 128 additions and 2 deletions

View File

@@ -2038,6 +2038,30 @@ h1 {
color: #0f4bb8; color: #0f4bb8;
} }
.bookmark-subpage__th-stack {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
}
.bookmark-subpage__column-filter {
width: 84px;
max-width: 100%;
border: 1px solid #cbd5e1;
border-radius: 4px;
background: #fff;
color: #111827;
font-size: 11px;
padding: 2px 6px;
}
.bookmark-subpage__column-filter:focus {
outline: 2px solid #93c5fd;
outline-offset: 0;
border-color: #60a5fa;
}
.bookmark-subpage__table th[draggable="true"] { .bookmark-subpage__table th[draggable="true"] {
cursor: move; cursor: move;
} }

View File

@@ -1,6 +1,7 @@
(function initTradeFairsSubpage() { (function initTradeFairsSubpage() {
const tableBody = document.getElementById('tradeFairTableBody'); const tableBody = document.getElementById('tradeFairTableBody');
const searchInput = document.getElementById('tradeFairSearchInput'); const searchInput = document.getElementById('tradeFairSearchInput');
const daysFilterInput = document.getElementById('tradeFairDaysFilterInput');
const meta = document.getElementById('tradeFairMeta'); const meta = document.getElementById('tradeFairMeta');
const columnSettingsBtn = document.getElementById('tradeFairColumnSettingsBtn'); const columnSettingsBtn = document.getElementById('tradeFairColumnSettingsBtn');
const columnsModal = document.getElementById('tradeFairColumnsModal'); const columnsModal = document.getElementById('tradeFairColumnsModal');
@@ -719,6 +720,7 @@
let sortKey = 'rang'; let sortKey = 'rang';
let sortDirection = 'asc'; let sortDirection = 'asc';
let searchTerm = ''; let searchTerm = '';
let daysFilterTerm = '';
let draggedColumnKey = null; let draggedColumnKey = null;
let lastOpenedByTradeFair = {}; let lastOpenedByTradeFair = {};
let columnVisibility = Object.fromEntries(DEFAULT_COLUMN_ORDER.map((key) => [key, true])); let columnVisibility = Object.fromEntries(DEFAULT_COLUMN_ORDER.map((key) => [key, true]));
@@ -853,6 +855,95 @@
return haystack.includes(term); return haystack.includes(term);
} }
function parseDaysFilter(term) {
const normalized = String(term || '').trim();
if (!normalized) {
return { type: 'all' };
}
const comparisonMatch = normalized.match(/^(<=|>=|!=|=|<|>)\s*(-?\d+)$/);
if (comparisonMatch) {
return {
type: 'comparison',
operator: comparisonMatch[1],
value: Number(comparisonMatch[2])
};
}
const rangeMatch = normalized.match(/^(-?\d+)\s*-\s*(-?\d+)$/);
if (rangeMatch) {
const first = Number(rangeMatch[1]);
const second = Number(rangeMatch[2]);
return {
type: 'range',
min: Math.min(first, second),
max: Math.max(first, second)
};
}
const exactMatch = normalized.match(/^-?\d+$/);
if (exactMatch) {
return {
type: 'comparison',
operator: '=',
value: Number(normalized)
};
}
return { type: 'invalid', raw: normalized };
}
function matchesDaysFilter(value, parsedFilter) {
if (!parsedFilter || parsedFilter.type === 'all' || parsedFilter.type === 'invalid') {
return true;
}
const numeric = toNumber(value);
if (numeric === null) {
return false;
}
if (parsedFilter.type === 'range') {
return numeric >= parsedFilter.min && numeric <= parsedFilter.max;
}
if (parsedFilter.type === 'comparison') {
switch (parsedFilter.operator) {
case '>':
return numeric > parsedFilter.value;
case '>=':
return numeric >= parsedFilter.value;
case '<':
return numeric < parsedFilter.value;
case '<=':
return numeric <= parsedFilter.value;
case '!=':
return numeric !== parsedFilter.value;
case '=':
default:
return numeric === parsedFilter.value;
}
}
return true;
}
function getDaysFilterMetaLabel(parsedFilter) {
if (!parsedFilter || parsedFilter.type === 'all') {
return '';
}
if (parsedFilter.type === 'invalid') {
return `Tage-bis-Start-Filter ungültig (${parsedFilter.raw})`;
}
if (parsedFilter.type === 'range') {
return `Tage-bis-Start-Filter ${parsedFilter.min}-${parsedFilter.max}`;
}
return `Tage-bis-Start-Filter ${parsedFilter.operator}${parsedFilter.value}`;
}
function sortRows(rows) { function sortRows(rows) {
return [...rows].sort((a, b) => { return [...rows].sort((a, b) => {
const aValue = getSortValue(a, sortKey); const aValue = getSortValue(a, sortKey);
@@ -1570,7 +1661,10 @@
function render() { function render() {
const normalizedRows = EFFECTIVE_TRADE_FAIRS.map(normalizeRow); const normalizedRows = EFFECTIVE_TRADE_FAIRS.map(normalizeRow);
const filtered = normalizedRows.filter((row) => matchesSearch(row, searchTerm)); const parsedDaysFilter = parseDaysFilter(daysFilterTerm);
const filtered = normalizedRows.filter(
(row) => matchesSearch(row, searchTerm) && matchesDaysFilter(row.tage_bis_start, parsedDaysFilter)
);
const sorted = sortRows(filtered); const sorted = sortRows(filtered);
const visibleColumnOrder = getVisibleColumnOrder(); const visibleColumnOrder = getVisibleColumnOrder();
@@ -1598,7 +1692,8 @@
const activeSortButton = sortButtons.find((button) => button.dataset.tradeSort === sortKey); const activeSortButton = sortButtons.find((button) => button.dataset.tradeSort === sortKey);
const sortLabel = activeSortButton?.dataset.baseLabel || sortKey; const sortLabel = activeSortButton?.dataset.baseLabel || sortKey;
meta.textContent = `${sorted.length} von ${EFFECTIVE_TRADE_FAIRS.length} Messen | Sortierung: ${sortLabel} (${sortDirection === 'asc' ? 'aufsteigend' : 'absteigend'})`; const daysFilterMeta = getDaysFilterMetaLabel(parsedDaysFilter);
meta.textContent = `${sorted.length} von ${EFFECTIVE_TRADE_FAIRS.length} Messen | Sortierung: ${sortLabel} (${sortDirection === 'asc' ? 'aufsteigend' : 'absteigend'})${daysFilterMeta ? ` | ${daysFilterMeta}` : ''}`;
} }
sortButtons.forEach((button) => { sortButtons.forEach((button) => {
@@ -1632,6 +1727,13 @@
render(); render();
}); });
if (daysFilterInput) {
daysFilterInput.addEventListener('input', () => {
daysFilterTerm = daysFilterInput.value.trim();
render();
});
}
lastOpenedByTradeFair = loadLastOpenedState(); lastOpenedByTradeFair = loadLastOpenedState();
loadColumnOrder(); loadColumnOrder();
loadColumnVisibility(); loadColumnVisibility();