Auto Task Assignment
This commit is contained in:
@@ -6,6 +6,7 @@ import '../../models/notification_item.dart';
|
||||
import '../../models/office.dart';
|
||||
import '../../models/profile.dart';
|
||||
import '../../models/task.dart';
|
||||
import '../../models/task_assignment.dart';
|
||||
import '../../models/ticket.dart';
|
||||
import '../../providers/notifications_provider.dart';
|
||||
import '../../providers/profile_provider.dart';
|
||||
@@ -55,6 +56,7 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen> {
|
||||
final profileAsync = ref.watch(currentProfileProvider);
|
||||
final notificationsAsync = ref.watch(notificationsProvider);
|
||||
final profilesAsync = ref.watch(profilesProvider);
|
||||
final assignmentsAsync = ref.watch(taskAssignmentsProvider);
|
||||
|
||||
final canCreate = profileAsync.maybeWhen(
|
||||
data: (profile) =>
|
||||
@@ -102,6 +104,22 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen> {
|
||||
];
|
||||
final staffOptions = _staffOptions(profilesAsync.valueOrNull);
|
||||
final statusOptions = _taskStatusOptions(tasks);
|
||||
|
||||
// derive latest assignee per task from task assignments stream
|
||||
final assignments =
|
||||
assignmentsAsync.valueOrNull ?? <TaskAssignment>[];
|
||||
final assignmentsByTask = <String, TaskAssignment>{};
|
||||
for (final a in assignments) {
|
||||
final current = assignmentsByTask[a.taskId];
|
||||
if (current == null || a.createdAt.isAfter(current.createdAt)) {
|
||||
assignmentsByTask[a.taskId] = a;
|
||||
}
|
||||
}
|
||||
final latestAssigneeByTaskId = <String, String?>{};
|
||||
for (final entry in assignmentsByTask.entries) {
|
||||
latestAssigneeByTaskId[entry.key] = entry.value.userId;
|
||||
}
|
||||
|
||||
final filteredTasks = _applyTaskFilters(
|
||||
tasks,
|
||||
ticketById: ticketById,
|
||||
@@ -110,6 +128,7 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen> {
|
||||
status: _selectedStatus,
|
||||
assigneeId: _selectedAssigneeId,
|
||||
dateRange: _selectedDateRange,
|
||||
latestAssigneeByTaskId: latestAssigneeByTaskId,
|
||||
);
|
||||
final summaryDashboard = _StatusSummaryRow(
|
||||
counts: _taskStatusCounts(filteredTasks),
|
||||
@@ -249,8 +268,10 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen> {
|
||||
),
|
||||
TasQColumn<Task>(
|
||||
header: 'Assigned Agent',
|
||||
cellBuilder: (context, task) =>
|
||||
Text(_assignedAgent(profileById, task.creatorId)),
|
||||
cellBuilder: (context, task) {
|
||||
final assigneeId = latestAssigneeByTaskId[task.id];
|
||||
return Text(_assignedAgent(profileById, assigneeId));
|
||||
},
|
||||
),
|
||||
TasQColumn<Task>(
|
||||
header: 'Status',
|
||||
@@ -271,7 +292,10 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen> {
|
||||
final officeName = officeId == null
|
||||
? 'Unassigned office'
|
||||
: (officeById[officeId]?.name ?? officeId);
|
||||
final assigned = _assignedAgent(profileById, task.creatorId);
|
||||
final assigned = _assignedAgent(
|
||||
profileById,
|
||||
latestAssigneeByTaskId[task.id],
|
||||
);
|
||||
final subtitle = _buildSubtitle(officeName, task.status);
|
||||
final hasMention = _hasTaskMention(notificationsAsync, task);
|
||||
final typingState = ref.watch(
|
||||
@@ -558,6 +582,7 @@ List<Task> _applyTaskFilters(
|
||||
required String? status,
|
||||
required String? assigneeId,
|
||||
required DateTimeRange? dateRange,
|
||||
required Map<String, String?> latestAssigneeByTaskId,
|
||||
}) {
|
||||
final query = subjectQuery.trim().toLowerCase();
|
||||
return tasks.where((task) {
|
||||
@@ -577,7 +602,8 @@ List<Task> _applyTaskFilters(
|
||||
if (status != null && task.status != status) {
|
||||
return false;
|
||||
}
|
||||
if (assigneeId != null && task.creatorId != assigneeId) {
|
||||
final currentAssignee = latestAssigneeByTaskId[task.id];
|
||||
if (assigneeId != null && currentAssignee != assigneeId) {
|
||||
return false;
|
||||
}
|
||||
if (dateRange != null) {
|
||||
|
||||
Reference in New Issue
Block a user