IT Service Request

This commit is contained in:
2026-03-08 07:54:20 +08:00
parent e4391ac465
commit 88432551c8
19 changed files with 4608 additions and 33 deletions
+58 -2
View File
@@ -23,6 +23,7 @@ import '../../providers/tasks_provider.dart';
import '../../providers/tickets_provider.dart';
import '../../providers/whereabouts_provider.dart';
import '../../providers/workforce_provider.dart';
import '../../providers/it_service_request_provider.dart';
import '../../widgets/responsive_body.dart';
import '../../widgets/reconnect_overlay.dart';
import '../../providers/realtime_controller.dart';
@@ -68,6 +69,7 @@ class StaffRowMetrics {
required this.whereabouts,
required this.ticketsRespondedToday,
required this.tasksClosedToday,
required this.eventsHandledToday,
});
final String userId;
@@ -76,6 +78,7 @@ class StaffRowMetrics {
final String whereabouts;
final int ticketsRespondedToday;
final int tasksClosedToday;
final int eventsHandledToday;
}
final dashboardMetricsProvider = Provider<AsyncValue<DashboardMetrics>>((ref) {
@@ -89,6 +92,8 @@ final dashboardMetricsProvider = Provider<AsyncValue<DashboardMetrics>>((ref) {
final positionsAsync = ref.watch(livePositionsProvider);
final leavesAsync = ref.watch(leavesProvider);
final passSlipsAsync = ref.watch(passSlipsProvider);
final isrAssignmentsAsync = ref.watch(itServiceRequestAssignmentsProvider);
final isrAsync = ref.watch(itServiceRequestsProvider);
final asyncValues = [
ticketsAsync,
@@ -424,14 +429,22 @@ final dashboardMetricsProvider = Provider<AsyncValue<DashboardMetrics>>((ref) {
whereabouts: whereabouts,
ticketsRespondedToday: ticketsResponded,
tasksClosedToday: tasksClosed,
eventsHandledToday: _countEventsHandledToday(
staff.id,
isrAssignmentsAsync.valueOrNull ?? [],
isrAsync.valueOrNull ?? [],
now,
),
);
}).toList();
// Order IT staff by combined activity (tickets responded today + tasks closed today)
// descending so most-active staff appear first. Use name as a stable tiebreaker.
staffRows.sort((a, b) {
final aCount = a.ticketsRespondedToday + a.tasksClosedToday;
final bCount = b.ticketsRespondedToday + b.tasksClosedToday;
final aCount =
a.ticketsRespondedToday + a.tasksClosedToday + a.eventsHandledToday;
final bCount =
b.ticketsRespondedToday + b.tasksClosedToday + b.eventsHandledToday;
if (bCount != aCount) return bCount.compareTo(aCount);
return a.name.compareTo(b.name);
});
@@ -452,6 +465,44 @@ final dashboardMetricsProvider = Provider<AsyncValue<DashboardMetrics>>((ref) {
);
});
int _countEventsHandledToday(
String userId,
List<dynamic> isrAssignments,
List<dynamic> isrList,
DateTime now,
) {
final startOfDay = DateTime(now.year, now.month, now.day);
final endOfDay = startOfDay.add(const Duration(days: 1));
// Find all ISR IDs assigned to this user
final assignedIsrIds = <String>{};
for (final a in isrAssignments) {
if (a.userId == userId) {
assignedIsrIds.add(a.requestId);
}
}
if (assignedIsrIds.isEmpty) return 0;
// Count ISRs that are in active status today
int count = 0;
for (final isr in isrList) {
if (!assignedIsrIds.contains(isr.id)) continue;
if (isr.status == 'in_progress' ||
isr.status == 'in_progress_dry_run' ||
isr.status == 'completed') {
// Check if event date or dry run date is today
final eventToday =
isr.eventDate != null &&
!isr.eventDate!.isBefore(startOfDay) &&
isr.eventDate!.isBefore(endOfDay);
final dryRunToday =
isr.dryRunDate != null &&
!isr.dryRunDate!.isBefore(startOfDay) &&
isr.dryRunDate!.isBefore(endOfDay);
if (eventToday || dryRunToday) count++;
}
}
return count;
}
class DashboardScreen extends StatefulWidget {
const DashboardScreen({super.key});
@@ -821,6 +872,7 @@ class _StaffTableHeader extends StatelessWidget {
Expanded(flex: 2, child: Text('Whereabouts', style: style)),
Expanded(flex: 2, child: Text('Tickets', style: style)),
Expanded(flex: 2, child: Text('Tasks', style: style)),
Expanded(flex: 2, child: Text('Events', style: style)),
],
);
}
@@ -920,6 +972,10 @@ class _StaffRow extends StatelessWidget {
flex: 2,
child: Text(row.tasksClosedToday.toString(), style: valueStyle),
),
Expanded(
flex: 2,
child: Text(row.eventsHandledToday.toString(), style: valueStyle),
),
],
),
);