| 672 | } |
| 673 | |
| 674 | public async Task<bool> MoveColumnAsync(int boardId, int columnId, int newOrder, int userId) |
| 675 | { |
| 676 | var board = await _db.Boards |
| 677 | .Include(b => b.Columns) |
| 678 | .Include(b => b.Members) |
| 679 | .Include(b => b.Workspace).ThenInclude(w => w.Members) |
| 680 | .FirstOrDefaultAsync(b => b.Id == boardId); |
| 681 | |
| 682 | if (board == null) return false; |
| 683 | |
| 684 | var isMember = board.OwnerId == userId |
| 685 | || board.Members.Any(m => m.UserId == userId && m.Status == "Accepted") |
| 686 | || (board.Workspace != null && board.Workspace.Members.Any(wm => wm.UserId == userId && wm.Status == "Accepted")); |
| 687 | |
| 688 | if (!isMember) return false; |
| 689 | |
| 690 | var column = board.Columns.FirstOrDefault(c => c.Id == columnId); |
| 691 | if (column == null) return false; |
| 692 | |
| 693 | // Current list sorted by Order |
| 694 | var columns = board.Columns.OrderBy(c => c.Order).ToList(); |
| 695 | |
| 696 | // Remove |
| 697 | columns.Remove(column); |
| 698 | |
| 699 | // Clamped insert |
| 700 | if (newOrder < 0) newOrder = 0; |
| 701 | if (newOrder > columns.Count) newOrder = columns.Count; |
| 702 | |
| 703 | columns.Insert(newOrder, column); |
| 704 | |
| 705 | // Re-assign Order |
| 706 | for (int i = 0; i < columns.Count; i++) |
| 707 | { |
| 708 | columns[i].Order = i; |
| 709 | } |
| 710 | |
| 711 | await _db.SaveChangesAsync(); |
| 712 | return true; |
| 713 | } |
| 714 | public async Task<bool> DeleteColumnAsync(int boardId, int columnId, int userId) |
| 715 | { |
| 716 | var board = await _db.Boards |