Statuskarten via Drag&Drop verschiebbar
Unteraufgaben lassen sich verschieben und bearbeiten
Dieser Commit ist enthalten in:
@ -179,12 +179,14 @@ class BoardManager {
|
||||
|
||||
const columnEl = createElement('div', {
|
||||
className: 'column',
|
||||
dataset: { columnId: column.id },
|
||||
draggable: 'true'
|
||||
dataset: { columnId: column.id }
|
||||
});
|
||||
|
||||
// Header with column color
|
||||
const header = createElement('div', { className: 'column-header' });
|
||||
// Header with column color - draggable
|
||||
const header = createElement('div', {
|
||||
className: 'column-header',
|
||||
draggable: 'true'
|
||||
});
|
||||
|
||||
// Apply column color to header background
|
||||
const columnColor = column.color || '#6B7280';
|
||||
@ -536,6 +538,7 @@ class BoardManager {
|
||||
|
||||
handleDragStart(e) {
|
||||
const taskCard = e.target.closest('.task-card');
|
||||
const header = e.target.closest('.column-header');
|
||||
const column = e.target.closest('.column');
|
||||
|
||||
if (taskCard) {
|
||||
@ -548,7 +551,8 @@ class BoardManager {
|
||||
type: 'task',
|
||||
taskId: parseInt(taskCard.dataset.taskId)
|
||||
});
|
||||
} else if (column && e.target.closest('.column-header')) {
|
||||
} else if (header && column) {
|
||||
// Header wird gezogen -> ganze Spalte verschieben
|
||||
this.draggedColumn = column;
|
||||
column.classList.add('dragging');
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
@ -575,6 +579,10 @@ class BoardManager {
|
||||
// Remove all drop indicators
|
||||
$$('.column-body.drag-over').forEach(el => el.classList.remove('drag-over'));
|
||||
$$('.drop-indicator').forEach(el => el.remove());
|
||||
// Remove column drag indicators
|
||||
$$('.column.drag-over-left, .column.drag-over-right').forEach(el => {
|
||||
el.classList.remove('drag-over-left', 'drag-over-right');
|
||||
});
|
||||
|
||||
store.setDragState(null);
|
||||
}
|
||||
@ -597,32 +605,44 @@ class BoardManager {
|
||||
}
|
||||
} else if (dragState.type === 'column') {
|
||||
const column = e.target.closest('.column');
|
||||
|
||||
// Entferne alle vorherigen Drag-Over-Klassen
|
||||
$$('.column.drag-over-left, .column.drag-over-right').forEach(col => {
|
||||
if (col !== column) {
|
||||
col.classList.remove('drag-over-left', 'drag-over-right');
|
||||
}
|
||||
});
|
||||
|
||||
if (column && column !== this.draggedColumn) {
|
||||
const rect = column.getBoundingClientRect();
|
||||
const midpoint = rect.left + rect.width / 2;
|
||||
|
||||
if (e.clientX < midpoint) {
|
||||
column.style.borderLeft = '3px solid var(--accent)';
|
||||
column.style.borderRight = '';
|
||||
column.classList.add('drag-over-left');
|
||||
column.classList.remove('drag-over-right');
|
||||
} else {
|
||||
column.style.borderRight = '3px solid var(--accent)';
|
||||
column.style.borderLeft = '';
|
||||
column.classList.add('drag-over-right');
|
||||
column.classList.remove('drag-over-left');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleDragLeave(e) {
|
||||
const columnBody = e.target.closest('.column-body');
|
||||
if (columnBody && !columnBody.contains(e.relatedTarget)) {
|
||||
columnBody.classList.remove('drag-over');
|
||||
$$('.drop-indicator', columnBody).forEach(el => el.remove());
|
||||
}
|
||||
const dragState = store.get('dragState');
|
||||
|
||||
const column = e.target.closest('.column');
|
||||
if (column) {
|
||||
column.style.borderLeft = '';
|
||||
column.style.borderRight = '';
|
||||
if (dragState?.type === 'task') {
|
||||
const columnBody = e.target.closest('.column-body');
|
||||
if (columnBody && !columnBody.contains(e.relatedTarget)) {
|
||||
columnBody.classList.remove('drag-over');
|
||||
$$('.drop-indicator', columnBody).forEach(el => el.remove());
|
||||
}
|
||||
} else if (dragState?.type === 'column') {
|
||||
const column = e.target.closest('.column');
|
||||
// Nur entfernen wenn wirklich die Spalte verlassen wird
|
||||
if (column && !column.contains(e.relatedTarget)) {
|
||||
column.classList.remove('drag-over-left', 'drag-over-right');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,18 +684,45 @@ class BoardManager {
|
||||
this.moveTask(taskId, columnId, position);
|
||||
} else if (dragState.type === 'column') {
|
||||
const targetColumn = e.target.closest('.column');
|
||||
if (!targetColumn || targetColumn === this.draggedColumn) return;
|
||||
|
||||
if (!targetColumn || targetColumn === this.draggedColumn) {
|
||||
// Cleanup
|
||||
$$('.column.drag-over-left, .column.drag-over-right').forEach(el => {
|
||||
el.classList.remove('drag-over-left', 'drag-over-right');
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const columns = store.get('columns');
|
||||
const fromIndex = columns.findIndex(c => c.id === dragState.columnId);
|
||||
const toIndex = columns.findIndex(c => c.id === parseInt(targetColumn.dataset.columnId));
|
||||
let toIndex = columns.findIndex(c => c.id === parseInt(targetColumn.dataset.columnId));
|
||||
|
||||
if (fromIndex !== -1 && toIndex !== -1) {
|
||||
// Berechne Position basierend auf Maus-Position (links oder rechts der Ziel-Spalte)
|
||||
const rect = targetColumn.getBoundingClientRect();
|
||||
const midpoint = rect.left + rect.width / 2;
|
||||
const dropOnRight = e.clientX > midpoint;
|
||||
|
||||
// Wenn rechts gedroppt und von links kommend, nach rechts verschieben
|
||||
if (dropOnRight && fromIndex < toIndex) {
|
||||
// toIndex bleibt gleich (Position nach der Ziel-Spalte)
|
||||
} else if (dropOnRight && fromIndex > toIndex) {
|
||||
// Von rechts kommend, rechts droppend -> nach der Ziel-Spalte
|
||||
toIndex = toIndex + 1;
|
||||
} else if (!dropOnRight && fromIndex > toIndex) {
|
||||
// toIndex bleibt gleich (Position vor der Ziel-Spalte)
|
||||
} else if (!dropOnRight && fromIndex < toIndex) {
|
||||
// Von links kommend, links droppend -> vor der Ziel-Spalte
|
||||
toIndex = toIndex - 1;
|
||||
}
|
||||
|
||||
if (fromIndex !== -1 && toIndex !== -1 && fromIndex !== toIndex) {
|
||||
this.reorderColumns(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
targetColumn.style.borderLeft = '';
|
||||
targetColumn.style.borderRight = '';
|
||||
// Cleanup
|
||||
$$('.column.drag-over-left, .column.drag-over-right').forEach(el => {
|
||||
el.classList.remove('drag-over-left', 'drag-over-right');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -948,7 +995,8 @@ class BoardManager {
|
||||
store.reorderColumns(columnIds);
|
||||
|
||||
try {
|
||||
await api.reorderColumns(projectId, columnIds);
|
||||
// API erwartet: columnId und newPosition
|
||||
await api.reorderColumns(projectId, moved.id, toIndex);
|
||||
syncManager.notifyColumnsReordered(columnIds);
|
||||
} catch (error) {
|
||||
console.error('Failed to reorder columns:', error);
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren