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:
@@ -828,7 +828,7 @@ router.post('/:id/duplicate', (req, res) => {
|
||||
router.put('/:id/archive', (req, res) => {
|
||||
try {
|
||||
const taskId = req.params.id;
|
||||
const { archived } = req.body;
|
||||
const { archived, columnId } = req.body;
|
||||
|
||||
const db = getDb();
|
||||
|
||||
@@ -837,16 +837,42 @@ router.put('/:id/archive', (req, res) => {
|
||||
return res.status(404).json({ error: 'Aufgabe nicht gefunden' });
|
||||
}
|
||||
|
||||
db.prepare('UPDATE tasks SET archived = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?')
|
||||
.run(archived ? 1 : 0, taskId);
|
||||
// Bei Wiederherstellung: Prüfen ob Spalte vorhanden
|
||||
if (!archived && !task.column_id) {
|
||||
// Task hat keine Spalte (wurde mit gelöschter Spalte archiviert)
|
||||
if (!columnId) {
|
||||
return res.status(400).json({
|
||||
error: 'Spalte erforderlich',
|
||||
requiresColumn: true
|
||||
});
|
||||
}
|
||||
// Prüfen ob Spalte existiert und zum Projekt gehört
|
||||
const column = db.prepare('SELECT * FROM columns WHERE id = ? AND project_id = ?')
|
||||
.get(columnId, task.project_id);
|
||||
if (!column) {
|
||||
return res.status(400).json({ error: 'Ungültige Spalte' });
|
||||
}
|
||||
// Wiederherstellen mit neuer Spalte
|
||||
db.prepare('UPDATE tasks SET archived = 0, column_id = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?')
|
||||
.run(columnId, taskId);
|
||||
} else {
|
||||
// Normales Archivieren/Wiederherstellen
|
||||
db.prepare('UPDATE tasks SET archived = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?')
|
||||
.run(archived ? 1 : 0, taskId);
|
||||
}
|
||||
|
||||
addHistory(db, taskId, req.user.id, archived ? 'archived' : 'restored');
|
||||
|
||||
logger.info(`Aufgabe ${archived ? 'archiviert' : 'wiederhergestellt'}: ${task.title}`);
|
||||
|
||||
// WebSocket
|
||||
// WebSocket - vollständige Task-Daten senden
|
||||
const io = req.app.get('io');
|
||||
io.to(`project:${task.project_id}`).emit('task:archived', { id: taskId, archived: !!archived });
|
||||
const updatedTask = getFullTask(db, taskId);
|
||||
io.to(`project:${task.project_id}`).emit('task:archived', {
|
||||
id: taskId,
|
||||
archived: !!archived,
|
||||
columnId: updatedTask?.columnId
|
||||
});
|
||||
|
||||
res.json({ message: archived ? 'Aufgabe archiviert' : 'Aufgabe wiederhergestellt' });
|
||||
} catch (error) {
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren