Remove TaskStatus enum and related extensions, refactor BoardService and BoardResponse models for improved API integration, and update BoardViewModel to handle card movements between columns. Adjust UI components to reflect these changes and enhance error handling for card operations.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../core/enums/task_status.dart';
|
||||
import '../core/utils/result.dart';
|
||||
import '../data/repositories/board_repositories.dart';
|
||||
import '../data/services/board_service.dart';
|
||||
import '../data/services/model/board_response/board_response.dart';
|
||||
|
||||
class BoardViewModel with ChangeNotifier {
|
||||
@@ -12,23 +12,27 @@ class BoardViewModel with ChangeNotifier {
|
||||
|
||||
bool _isLoading = false;
|
||||
String? _errorMessage;
|
||||
List<BoardData> _boardData = [];
|
||||
Board? _board;
|
||||
|
||||
bool get isLoading => _isLoading;
|
||||
String? get errorMessage => _errorMessage;
|
||||
List<BoardData> get boardData => _boardData;
|
||||
bool get hasData => _boardData.isNotEmpty;
|
||||
Board? get board => _board;
|
||||
List<BoardColumn> get columns => _board?.columns ?? const [];
|
||||
bool get hasData => _board != null && columns.isNotEmpty;
|
||||
|
||||
Future<void> getBoard() async {
|
||||
_isLoading = true;
|
||||
_errorMessage = null;
|
||||
notifyListeners();
|
||||
|
||||
final result = await _boardRepository.getBoard();
|
||||
|
||||
switch (result) {
|
||||
case Ok<BoardResponse>():
|
||||
// تبدیل به لیست قابل تغییر
|
||||
_boardData = List.from(result.value.data ?? []);
|
||||
_board = result.value.data?.board;
|
||||
if (_board == null) {
|
||||
_errorMessage = result.value.error?.message ?? 'No board data';
|
||||
}
|
||||
break;
|
||||
case Error<BoardResponse>():
|
||||
_errorMessage = result.error.toString();
|
||||
@@ -38,40 +42,72 @@ class BoardViewModel with ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// update task status
|
||||
void updateTaskStatus(String taskId, String newStatus) {
|
||||
final taskIndex = _boardData.indexWhere((task) => task.id == taskId);
|
||||
if (taskIndex != -1) {
|
||||
_boardData[taskIndex] = _boardData[taskIndex].copyWith(status: newStatus);
|
||||
/// Look up the column a given card currently lives in.
|
||||
BoardColumn? columnForCard(String cardId) {
|
||||
for (final column in columns) {
|
||||
if (column.cards.any((c) => c.id == cardId)) return column;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Move a card to [targetColumnId] at the end of that column.
|
||||
/// Optimistically updates local state, then calls the API; rolls back on
|
||||
/// failure.
|
||||
Future<Result<MoveCardResponse>> moveCard({
|
||||
required BoardCard card,
|
||||
required BoardColumn targetColumn,
|
||||
}) async {
|
||||
final cardId = card.id;
|
||||
final targetColumnId = targetColumn.id;
|
||||
if (cardId == null || targetColumnId == null || _board == null) {
|
||||
return Result.error(Exception('Invalid card or column'));
|
||||
}
|
||||
|
||||
final sourceColumn = columnForCard(cardId);
|
||||
if (sourceColumn == null) {
|
||||
return Result.error(Exception('Card not found in any column'));
|
||||
}
|
||||
if (sourceColumn.id == targetColumnId) {
|
||||
return Result.ok(MoveCardResponse(success: true, message: 'No change'));
|
||||
}
|
||||
|
||||
final previousColumns = _board!.columns;
|
||||
final newOrder = targetColumn.cards.length;
|
||||
|
||||
_board = _board!.copyWith(
|
||||
columns:
|
||||
previousColumns.map((column) {
|
||||
if (column.id == sourceColumn.id) {
|
||||
final remaining =
|
||||
column.cards.where((c) => c.id != cardId).toList();
|
||||
return column.copyWith(
|
||||
cards: remaining,
|
||||
cardCount: remaining.length,
|
||||
);
|
||||
}
|
||||
if (column.id == targetColumnId) {
|
||||
final updated = List<BoardCard>.from(column.cards)
|
||||
..add(card.copyWith(columnId: targetColumnId, order: newOrder));
|
||||
return column.copyWith(
|
||||
cards: updated,
|
||||
cardCount: updated.length,
|
||||
);
|
||||
}
|
||||
return column;
|
||||
}).toList(),
|
||||
);
|
||||
notifyListeners();
|
||||
|
||||
final result = await _boardRepository.moveCard(
|
||||
cardId: cardId,
|
||||
columnId: targetColumnId,
|
||||
newOrder: newOrder,
|
||||
);
|
||||
|
||||
if (result is Error<MoveCardResponse>) {
|
||||
_board = _board!.copyWith(columns: previousColumns);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
bool isValidMove(TaskStatus currentStatus, TaskStatus targetStatus) {
|
||||
if (currentStatus == TaskStatus.toDo) {
|
||||
return targetStatus == TaskStatus.inProgress;
|
||||
} else if (currentStatus == TaskStatus.inProgress) {
|
||||
return targetStatus == TaskStatus.toDo || targetStatus == TaskStatus.done;
|
||||
} else if (currentStatus == TaskStatus.done) {
|
||||
return targetStatus == TaskStatus.inProgress;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
List<BoardData> getTasksByStatus(TaskStatus status) {
|
||||
return boardData.where((task) => task.status == status.value).toList();
|
||||
}
|
||||
|
||||
void _updateTaskStatus(BoardData task, TaskStatus newStatus) {
|
||||
if (task.status == newStatus.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
final oldStatus = task.status;
|
||||
|
||||
// update task status in ViewModel
|
||||
updateTaskStatus(task.id!, newStatus.value);
|
||||
|
||||
// _showStatusChangeMessage(context, task, oldStatus, newStatus);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user