feat: Enhance dashboard refresh logic; add handling for various notification types and improve method organization
This commit is contained in:
parent
7d5d2b5bf4
commit
25b20fedda
@ -70,9 +70,9 @@ class DashboardController extends GetxController {
|
||||
ever(projectSelectedRange, (_) => fetchProjectProgress());
|
||||
}
|
||||
|
||||
/// =========================
|
||||
/// Helper Methods
|
||||
/// =========================
|
||||
// =========================
|
||||
// Helper Methods
|
||||
// =========================
|
||||
int _getDaysFromRange(String range) {
|
||||
switch (range) {
|
||||
case '7D':
|
||||
@ -114,21 +114,28 @@ class DashboardController extends GetxController {
|
||||
logSafe('Project chart view toggled to: $isChart', level: LogLevel.debug);
|
||||
}
|
||||
|
||||
/// =========================
|
||||
/// Manual refresh
|
||||
/// =========================
|
||||
// =========================
|
||||
// Manual Refresh Methods
|
||||
// =========================
|
||||
Future<void> refreshDashboard() async {
|
||||
logSafe('Manual dashboard refresh triggered.', level: LogLevel.debug);
|
||||
await fetchAllDashboardData();
|
||||
}
|
||||
|
||||
/// =========================
|
||||
/// Fetch all dashboard data
|
||||
/// =========================
|
||||
Future<void> refreshAttendance() async => fetchRoleWiseAttendance();
|
||||
Future<void> refreshTasks() async {
|
||||
final projectId = projectController.selectedProjectId.value;
|
||||
if (projectId.isNotEmpty) await fetchDashboardTasks(projectId: projectId);
|
||||
}
|
||||
|
||||
Future<void> refreshProjects() async => fetchProjectProgress();
|
||||
|
||||
// =========================
|
||||
// Fetch All Dashboard Data
|
||||
// =========================
|
||||
Future<void> fetchAllDashboardData() async {
|
||||
final String projectId = projectController.selectedProjectId.value;
|
||||
|
||||
// Skip fetching if no project is selected
|
||||
if (projectId.isEmpty) {
|
||||
logSafe('No project selected. Skipping dashboard API calls.',
|
||||
level: LogLevel.warning);
|
||||
@ -143,17 +150,15 @@ class DashboardController extends GetxController {
|
||||
]);
|
||||
}
|
||||
|
||||
/// =========================
|
||||
/// API Calls
|
||||
/// =========================
|
||||
// =========================
|
||||
// API Calls
|
||||
// =========================
|
||||
Future<void> fetchRoleWiseAttendance() async {
|
||||
final String projectId = projectController.selectedProjectId.value;
|
||||
|
||||
if (projectId.isEmpty) return;
|
||||
|
||||
try {
|
||||
isAttendanceLoading.value = true;
|
||||
|
||||
final List<dynamic>? response =
|
||||
await ApiService.getDashboardAttendanceOverview(
|
||||
projectId, getAttendanceDays());
|
||||
@ -179,16 +184,12 @@ class DashboardController extends GetxController {
|
||||
|
||||
Future<void> fetchProjectProgress() async {
|
||||
final String projectId = projectController.selectedProjectId.value;
|
||||
|
||||
if (projectId.isEmpty) return;
|
||||
|
||||
try {
|
||||
isProjectLoading.value = true;
|
||||
|
||||
final response = await ApiService.getProjectProgress(
|
||||
projectId: projectId,
|
||||
days: getProjectDays(),
|
||||
);
|
||||
projectId: projectId, days: getProjectDays());
|
||||
|
||||
if (response != null && response.success) {
|
||||
projectChartData.value =
|
||||
@ -208,11 +209,10 @@ class DashboardController extends GetxController {
|
||||
}
|
||||
|
||||
Future<void> fetchDashboardTasks({required String projectId}) async {
|
||||
if (projectId.isEmpty) return; // Skip if empty
|
||||
if (projectId.isEmpty) return;
|
||||
|
||||
try {
|
||||
isTasksLoading.value = true;
|
||||
|
||||
final response = await ApiService.getDashboardTasks(projectId: projectId);
|
||||
|
||||
if (response != null && response.success) {
|
||||
@ -235,11 +235,10 @@ class DashboardController extends GetxController {
|
||||
}
|
||||
|
||||
Future<void> fetchDashboardTeams({required String projectId}) async {
|
||||
if (projectId.isEmpty) return; // Skip if empty
|
||||
if (projectId.isEmpty) return;
|
||||
|
||||
try {
|
||||
isTeamsLoading.value = true;
|
||||
|
||||
final response = await ApiService.getDashboardTeams(projectId: projectId);
|
||||
|
||||
if (response != null && response.success) {
|
||||
|
@ -9,8 +9,9 @@ import 'package:marco/controller/expense/expense_detail_controller.dart';
|
||||
import 'package:marco/controller/directory/directory_controller.dart';
|
||||
import 'package:marco/controller/directory/notes_controller.dart';
|
||||
import 'package:marco/controller/document/user_document_controller.dart';
|
||||
import 'package:marco/helpers/utils/permission_constants.dart';
|
||||
import 'package:marco/controller/document/document_details_controller.dart';
|
||||
import 'package:marco/controller/dashboard/dashboard_controller.dart';
|
||||
import 'package:marco/helpers/utils/permission_constants.dart';
|
||||
|
||||
/// Handles incoming FCM notification actions and updates UI/controllers.
|
||||
class NotificationActionHandler {
|
||||
@ -46,6 +47,10 @@ class NotificationActionHandler {
|
||||
break;
|
||||
case 'attendance_updated':
|
||||
_handleAttendanceUpdated(data);
|
||||
_handleDashboardUpdate(data); // refresh dashboard attendance
|
||||
break;
|
||||
case 'dashboard_update':
|
||||
_handleDashboardUpdate(data); // full dashboard refresh
|
||||
break;
|
||||
default:
|
||||
_logger.w('⚠️ Unknown notification type: $type');
|
||||
@ -60,16 +65,19 @@ class NotificationActionHandler {
|
||||
case 'Attendance':
|
||||
if (_isAttendanceAction(action)) {
|
||||
_handleAttendanceUpdated(data);
|
||||
_handleDashboardUpdate(data);
|
||||
}
|
||||
break;
|
||||
|
||||
/// 🔹 Tasks
|
||||
case 'Report_Task':
|
||||
_handleTaskUpdated(data, isComment: false);
|
||||
_handleDashboardUpdate(data);
|
||||
break;
|
||||
|
||||
case 'Task_Comment':
|
||||
_handleTaskUpdated(data, isComment: true);
|
||||
_handleDashboardUpdate(data);
|
||||
break;
|
||||
|
||||
case 'Task_Modified':
|
||||
@ -77,11 +85,13 @@ class NotificationActionHandler {
|
||||
case 'Floor_Modified':
|
||||
case 'Building_Modified':
|
||||
_handleTaskPlanningUpdated(data);
|
||||
_handleDashboardUpdate(data);
|
||||
break;
|
||||
|
||||
/// 🔹 Expenses
|
||||
case 'Expenses_Modified':
|
||||
_handleExpenseUpdated(data);
|
||||
_handleDashboardUpdate(data);
|
||||
break;
|
||||
|
||||
/// 🔹 Documents
|
||||
@ -198,59 +208,55 @@ class NotificationActionHandler {
|
||||
}
|
||||
|
||||
/// ---------------------- DOCUMENT HANDLER ----------------------
|
||||
/// ---------------------- DOCUMENT HANDLER ----------------------
|
||||
static void _handleDocumentModified(Map<String, dynamic> data) {
|
||||
late String entityTypeId;
|
||||
late String entityId;
|
||||
String? documentId = data['DocumentId'];
|
||||
static void _handleDocumentModified(Map<String, dynamic> data) {
|
||||
late String entityTypeId;
|
||||
late String entityId;
|
||||
String? documentId = data['DocumentId'];
|
||||
|
||||
if (data['Keyword'] == 'Employee_Document_Modified') {
|
||||
entityTypeId = Permissions.employeeEntity;
|
||||
entityId = data['EmployeeId'] ?? '';
|
||||
} else if (data['Keyword'] == 'Project_Document_Modified') {
|
||||
entityTypeId = Permissions.projectEntity;
|
||||
entityId = data['ProjectId'] ?? '';
|
||||
} else {
|
||||
_logger.w("⚠️ Document update received with unknown keyword: $data");
|
||||
return;
|
||||
}
|
||||
if (data['Keyword'] == 'Employee_Document_Modified') {
|
||||
entityTypeId = Permissions.employeeEntity;
|
||||
entityId = data['EmployeeId'] ?? '';
|
||||
} else if (data['Keyword'] == 'Project_Document_Modified') {
|
||||
entityTypeId = Permissions.projectEntity;
|
||||
entityId = data['ProjectId'] ?? '';
|
||||
} else {
|
||||
_logger.w("⚠️ Document update received with unknown keyword: $data");
|
||||
return;
|
||||
}
|
||||
|
||||
if (entityId.isEmpty) {
|
||||
_logger.w("⚠️ Document update missing entityId: $data");
|
||||
return;
|
||||
}
|
||||
if (entityId.isEmpty) {
|
||||
_logger.w("⚠️ Document update missing entityId: $data");
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔹 Refresh document list
|
||||
_safeControllerUpdate<DocumentController>(
|
||||
onFound: (controller) async {
|
||||
await controller.fetchDocuments(
|
||||
entityTypeId: entityTypeId,
|
||||
entityId: entityId,
|
||||
reset: true,
|
||||
);
|
||||
},
|
||||
notFoundMessage: '⚠️ DocumentController not found, cannot refresh list.',
|
||||
successMessage: '✅ DocumentController refreshed from notification.',
|
||||
);
|
||||
|
||||
// 🔹 Refresh document details (if opened)
|
||||
if (documentId != null) {
|
||||
_safeControllerUpdate<DocumentDetailsController>(
|
||||
_safeControllerUpdate<DocumentController>(
|
||||
onFound: (controller) async {
|
||||
if (controller.documentDetails.value?.data?.id == documentId) {
|
||||
await controller.fetchDocumentDetails(documentId);
|
||||
_logger.i("✅ DocumentDetailsController refreshed for Document $documentId");
|
||||
}
|
||||
await controller.fetchDocuments(
|
||||
entityTypeId: entityTypeId,
|
||||
entityId: entityId,
|
||||
reset: true,
|
||||
);
|
||||
},
|
||||
notFoundMessage: 'ℹ️ DocumentDetailsController not active, skipping.',
|
||||
successMessage: '✅ DocumentDetailsController checked for refresh.',
|
||||
notFoundMessage: '⚠️ DocumentController not found, cannot refresh list.',
|
||||
successMessage: '✅ DocumentController refreshed from notification.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (documentId != null) {
|
||||
_safeControllerUpdate<DocumentDetailsController>(
|
||||
onFound: (controller) async {
|
||||
if (controller.documentDetails.value?.data?.id == documentId) {
|
||||
await controller.fetchDocumentDetails(documentId);
|
||||
_logger.i(
|
||||
"✅ DocumentDetailsController refreshed for Document $documentId");
|
||||
}
|
||||
},
|
||||
notFoundMessage: 'ℹ️ DocumentDetailsController not active, skipping.',
|
||||
successMessage: '✅ DocumentDetailsController checked for refresh.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// ---------------------- DIRECTORY HANDLERS ----------------------
|
||||
|
||||
static void _handleContactModified(Map<String, dynamic> data) {
|
||||
_safeControllerUpdate<DirectoryController>(
|
||||
onFound: (controller) => controller.fetchContacts(),
|
||||
@ -296,6 +302,32 @@ static void _handleDocumentModified(Map<String, dynamic> data) {
|
||||
);
|
||||
}
|
||||
|
||||
/// ---------------------- DASHBOARD HANDLER ----------------------
|
||||
static void _handleDashboardUpdate(Map<String, dynamic> data) {
|
||||
_safeControllerUpdate<DashboardController>(
|
||||
onFound: (controller) async {
|
||||
final type = data['type'] ?? '';
|
||||
switch (type) {
|
||||
case 'attendance_updated':
|
||||
await controller.fetchRoleWiseAttendance();
|
||||
break;
|
||||
case 'task_updated':
|
||||
await controller.fetchDashboardTasks(
|
||||
projectId: controller.projectController.selectedProjectId.value);
|
||||
break;
|
||||
case 'project_progress_update':
|
||||
await controller.fetchProjectProgress();
|
||||
break;
|
||||
case 'full_dashboard_refresh':
|
||||
default:
|
||||
await controller.refreshDashboard();
|
||||
}
|
||||
},
|
||||
notFoundMessage: '⚠️ DashboardController not found, cannot refresh.',
|
||||
successMessage: '✅ DashboardController refreshed from notification.',
|
||||
);
|
||||
}
|
||||
|
||||
/// ---------------------- UTILITY ----------------------
|
||||
|
||||
static void _safeControllerUpdate<T>({
|
||||
|
Loading…
x
Reference in New Issue
Block a user