Implement direct days-until-start column filter
This commit is contained in:
@@ -2038,6 +2038,30 @@ h1 {
|
||||
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"] {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(function initTradeFairsSubpage() {
|
||||
const tableBody = document.getElementById('tradeFairTableBody');
|
||||
const searchInput = document.getElementById('tradeFairSearchInput');
|
||||
const daysFilterInput = document.getElementById('tradeFairDaysFilterInput');
|
||||
const meta = document.getElementById('tradeFairMeta');
|
||||
const columnSettingsBtn = document.getElementById('tradeFairColumnSettingsBtn');
|
||||
const columnsModal = document.getElementById('tradeFairColumnsModal');
|
||||
@@ -719,6 +720,7 @@
|
||||
let sortKey = 'rang';
|
||||
let sortDirection = 'asc';
|
||||
let searchTerm = '';
|
||||
let daysFilterTerm = '';
|
||||
let draggedColumnKey = null;
|
||||
let lastOpenedByTradeFair = {};
|
||||
let columnVisibility = Object.fromEntries(DEFAULT_COLUMN_ORDER.map((key) => [key, true]));
|
||||
@@ -853,6 +855,95 @@
|
||||
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) {
|
||||
return [...rows].sort((a, b) => {
|
||||
const aValue = getSortValue(a, sortKey);
|
||||
@@ -1570,7 +1661,10 @@
|
||||
|
||||
function render() {
|
||||
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 visibleColumnOrder = getVisibleColumnOrder();
|
||||
|
||||
@@ -1598,7 +1692,8 @@
|
||||
|
||||
const activeSortButton = sortButtons.find((button) => button.dataset.tradeSort === 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) => {
|
||||
@@ -1632,6 +1727,13 @@
|
||||
render();
|
||||
});
|
||||
|
||||
if (daysFilterInput) {
|
||||
daysFilterInput.addEventListener('input', () => {
|
||||
daysFilterTerm = daysFilterInput.value.trim();
|
||||
render();
|
||||
});
|
||||
}
|
||||
|
||||
lastOpenedByTradeFair = loadLastOpenedState();
|
||||
loadColumnOrder();
|
||||
loadColumnVisibility();
|
||||
|
||||
Reference in New Issue
Block a user