Datenbank bereinigt / Gitea-Integration gefixt
Dieser Commit ist enthalten in:
committet von
Server Deploy
Ursprung
395598c2b0
Commit
c21be47428
@ -86,6 +86,13 @@ class ListViewManager {
|
||||
this.contentElement.addEventListener('click', (e) => this.handleContentClick(e));
|
||||
this.contentElement.addEventListener('change', (e) => this.handleContentChange(e));
|
||||
this.contentElement.addEventListener('dblclick', (e) => this.handleDoubleClick(e));
|
||||
|
||||
// Stop editing when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (this.editingCell && !this.editingCell.contains(e.target)) {
|
||||
this.stopEditing();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,19 +414,53 @@ class ListViewManager {
|
||||
const users = store.get('users');
|
||||
const cell = createElement('div', { className: 'list-cell list-cell-assignee list-cell-editable' });
|
||||
|
||||
const assignedUser = users.find(u => u.id === task.assignedTo);
|
||||
|
||||
// Avatar
|
||||
if (assignedUser) {
|
||||
const avatar = createElement('div', {
|
||||
className: 'avatar',
|
||||
style: { backgroundColor: assignedUser.color || '#6366F1' }
|
||||
}, [getInitials(assignedUser.displayName)]);
|
||||
cell.appendChild(avatar);
|
||||
// Sammle alle zugewiesenen Benutzer aus assignees Array
|
||||
const assignedUserIds = new Set();
|
||||
|
||||
// Verwende das assignees Array vom Backend
|
||||
if (task.assignees && Array.isArray(task.assignees)) {
|
||||
task.assignees.forEach(assignee => {
|
||||
if (assignee && assignee.id) {
|
||||
assignedUserIds.add(assignee.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Fallback: Füge assigned_to hinzu falls assignees leer ist
|
||||
if (assignedUserIds.size === 0 && task.assignedTo) {
|
||||
assignedUserIds.add(task.assignedTo);
|
||||
}
|
||||
|
||||
// User dropdown
|
||||
// Container für mehrere Avatare
|
||||
const avatarContainer = createElement('div', { className: 'avatar-container' });
|
||||
|
||||
if (assignedUserIds.size > 0) {
|
||||
// Erstelle Avatar für jeden zugewiesenen Benutzer
|
||||
Array.from(assignedUserIds).forEach(userId => {
|
||||
const user = users.find(u => u.id === userId);
|
||||
if (user) {
|
||||
const avatar = createElement('div', {
|
||||
className: 'avatar',
|
||||
style: { backgroundColor: user.color || '#6366F1' },
|
||||
title: user.displayName // Tooltip zeigt Name beim Hover
|
||||
}, [getInitials(user.displayName)]);
|
||||
avatarContainer.appendChild(avatar);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Placeholder für "nicht zugewiesen"
|
||||
const placeholder = createElement('div', {
|
||||
className: 'avatar avatar-empty',
|
||||
title: 'Nicht zugewiesen'
|
||||
}, ['?']);
|
||||
avatarContainer.appendChild(placeholder);
|
||||
}
|
||||
|
||||
cell.appendChild(avatarContainer);
|
||||
|
||||
// User dropdown (versteckt, nur für Bearbeitung)
|
||||
const select = createElement('select', {
|
||||
className: 'assignee-select hidden',
|
||||
dataset: { field: 'assignedTo', taskId: task.id }
|
||||
});
|
||||
|
||||
@ -445,6 +486,24 @@ class ListViewManager {
|
||||
// =====================
|
||||
|
||||
handleContentClick(e) {
|
||||
// Handle avatar click for assignee editing
|
||||
if (e.target.classList.contains('avatar') || e.target.classList.contains('avatar-empty')) {
|
||||
const cell = e.target.closest('.list-cell-assignee');
|
||||
if (cell) {
|
||||
this.startEditingAssignee(cell);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle click on avatar container (wenn man neben Avatar klickt)
|
||||
if (e.target.classList.contains('avatar-container')) {
|
||||
const cell = e.target.closest('.list-cell-assignee');
|
||||
if (cell) {
|
||||
this.startEditingAssignee(cell);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const target = e.target.closest('[data-action]');
|
||||
if (!target) return;
|
||||
|
||||
@ -456,6 +515,35 @@ class ListViewManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start editing assignee
|
||||
*/
|
||||
startEditingAssignee(cell) {
|
||||
// Stop any current editing
|
||||
this.stopEditing();
|
||||
|
||||
// Add editing class to show dropdown and hide avatar
|
||||
cell.classList.add('editing');
|
||||
|
||||
// Focus the select element
|
||||
const select = cell.querySelector('.assignee-select');
|
||||
if (select) {
|
||||
select.focus();
|
||||
}
|
||||
|
||||
this.editingCell = cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop editing
|
||||
*/
|
||||
stopEditing() {
|
||||
if (this.editingCell) {
|
||||
this.editingCell.classList.remove('editing');
|
||||
this.editingCell = null;
|
||||
}
|
||||
}
|
||||
|
||||
handleContentChange(e) {
|
||||
const target = e.target;
|
||||
const field = target.dataset.field;
|
||||
@ -463,6 +551,11 @@ class ListViewManager {
|
||||
|
||||
if (field && taskId) {
|
||||
this.updateTaskField(parseInt(taskId), field, target.value);
|
||||
|
||||
// Stop editing after change for assignee field
|
||||
if (field === 'assignedTo') {
|
||||
this.stopEditing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren