UI-Redesign: AegisSight Design, Filter-Popover, Header-Umbau

- Session-Timeout auf 60 Minuten erhöht (ACCESS_TOKEN_EXPIRY + SESSION_TIMEOUT)
- AegisSight Light Theme: Gold-Akzent (#C8A851) statt Indigo
- Navigation-Tabs in eigene Zeile unter Header verschoben (HTML-Struktur)
- Filter-Bar durch kompaktes Popover mit Checkboxen ersetzt (Mehrfachauswahl)
- Archiv-Funktion repariert (lädt jetzt per API statt leerem Store)
- Filter-Bugs behoben: Reset-Button ID, Default-Werte, Ohne-Datum-Filter
- Mehrspalten-Layout Feature entfernt
- Online-Status vom Header an User-Avatar verschoben (grüner Punkt)
- Lupen-Icon entfernt
- CLAUDE.md: Docker-Deploy und CSS-Tricks Regeln aktualisiert

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
Server Deploy
2026-03-19 18:49:38 +01:00
Ursprung 99a6b7437b
Commit 4bd57d653f
36 geänderte Dateien mit 5027 neuen und 2897 gelöschten Zeilen

Datei anzeigen

@@ -492,37 +492,55 @@ export function filterTasks(tasks, filters, searchResultIds = [], columns = [])
}
}
// Priority filter
if (filters.priority && filters.priority !== 'all') {
if (task.priority !== filters.priority) return false;
// Priority filter (string or array)
if (filters.priority && filters.priority.length > 0) {
const priorityFilter = Array.isArray(filters.priority) ? filters.priority : [filters.priority];
if (!priorityFilter.includes(task.priority)) return false;
}
// Assignee filter
if (filters.assignee && filters.assignee !== 'all') {
if (task.assignedTo !== parseInt(filters.assignee)) return false;
// Assignee filter (string or array)
if (filters.assignee && filters.assignee.length > 0) {
const assigneeFilter = Array.isArray(filters.assignee) ? filters.assignee : [filters.assignee];
const assigneeIds = assigneeFilter.map(id => parseInt(id));
const taskAssigneeId = task.assignedTo;
const taskAssignees = task.assignees?.map(a => a.id || a) || [];
const matches = assigneeIds.some(id => id === taskAssigneeId || taskAssignees.includes(id));
if (!matches) return false;
}
// Label filter
if (filters.label && filters.label !== 'all') {
const hasLabel = task.labels?.some(l => l.id === parseInt(filters.label));
// Label filter (string or array)
if (filters.label && filters.label.length > 0) {
const labelFilter = Array.isArray(filters.label) ? filters.label : [filters.label];
const labelIds = labelFilter.map(id => parseInt(id));
const hasLabel = task.labels?.some(l => labelIds.includes(l.id));
if (!hasLabel) return false;
}
// Due date filter
if (filters.dueDate && filters.dueDate !== 'all' && filters.dueDate !== '') {
const status = getDueDateStatus(task.dueDate);
// Due date filter (string or array)
if (filters.dueDate && filters.dueDate.length > 0) {
const dueDateFilter = Array.isArray(filters.dueDate) ? filters.dueDate : [filters.dueDate];
let matches = false;
// Bei "überfällig" erledigte Aufgaben ausschließen
if (filters.dueDate === 'overdue') {
if (status !== 'overdue' || isTaskCompleted(task)) return false;
}
if (filters.dueDate === 'today' && status !== 'today') return false;
if (filters.dueDate === 'week') {
const due = new Date(task.dueDate);
const weekFromNow = new Date();
weekFromNow.setDate(weekFromNow.getDate() + 7);
if (!task.dueDate || due > weekFromNow) return false;
for (const filterVal of dueDateFilter) {
if (filterVal === 'none') {
if (!task.dueDate) { matches = true; break; }
} else if (filterVal === 'overdue') {
const status = getDueDateStatus(task.dueDate);
if (status === 'overdue' && !isTaskCompleted(task)) { matches = true; break; }
} else if (filterVal === 'today') {
const status = getDueDateStatus(task.dueDate);
if (status === 'today') { matches = true; break; }
} else if (filterVal === 'week') {
if (task.dueDate) {
const due = new Date(task.dueDate);
const weekFromNow = new Date();
weekFromNow.setDate(weekFromNow.getDate() + 7);
if (due <= weekFromNow) { matches = true; break; }
}
}
}
if (!matches) return false;
}
return true;