refactor: Clean up attendance controller initialization and enhance project change handling
This commit is contained in:
parent
ebc8996f71
commit
c78c14e409
@ -51,11 +51,6 @@ class AttendanceController extends GetxController {
|
||||
super.onInit();
|
||||
_initializeDefaults();
|
||||
|
||||
// 🔹 Fetch organizations for the selected project
|
||||
final projectId = Get.find<ProjectController>().selectedProject?.id;
|
||||
if (projectId != null) {
|
||||
fetchOrganizations(projectId);
|
||||
}
|
||||
}
|
||||
|
||||
void _initializeDefaults() {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
class ApiEndpoints {
|
||||
static const String baseUrl = "https://stageapi.marcoaiot.com/api";
|
||||
// static const String baseUrl = "https://api.marcoaiot.com/api";
|
||||
// static const String baseUrl = "https://stageapi.marcoaiot.com/api";
|
||||
static const String baseUrl = "https://api.marcoaiot.com/api";
|
||||
// static const String baseUrl = "https://devapi.marcoaiot.com/api";
|
||||
|
||||
// Dashboard Module API Endpoints
|
||||
|
||||
@ -69,7 +69,6 @@ class NotificationActionHandler {
|
||||
}
|
||||
break;
|
||||
case 'Team_Modified':
|
||||
// Call method to handle team modifications and dashboard update
|
||||
_handleDashboardUpdate(data);
|
||||
break;
|
||||
|
||||
@ -129,6 +128,11 @@ class NotificationActionHandler {
|
||||
/// ---------------------- HANDLERS ----------------------
|
||||
|
||||
static void _handleTaskPlanningUpdated(Map<String, dynamic> data) {
|
||||
if (!_isCurrentProject(data)) {
|
||||
_logger.i("ℹ️ Ignored task planning update from another project.");
|
||||
return;
|
||||
}
|
||||
|
||||
final projectId = data['ProjectId'];
|
||||
if (projectId == null) {
|
||||
_logger.w("⚠️ TaskPlanning update received without ProjectId: $data");
|
||||
@ -159,13 +163,17 @@ class NotificationActionHandler {
|
||||
}
|
||||
|
||||
static void _handleExpenseUpdated(Map<String, dynamic> data) {
|
||||
if (!_isCurrentProject(data)) {
|
||||
_logger.i("ℹ️ Ignored expense update from another project.");
|
||||
return;
|
||||
}
|
||||
|
||||
final expenseId = data['ExpenseId'];
|
||||
if (expenseId == null) {
|
||||
_logger.w("⚠️ Expense update received without ExpenseId: $data");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update Expense List
|
||||
_safeControllerUpdate<ExpenseController>(
|
||||
onFound: (controller) async {
|
||||
await controller.fetchExpenses();
|
||||
@ -175,7 +183,6 @@ class NotificationActionHandler {
|
||||
'✅ ExpenseController refreshed from expense notification.',
|
||||
);
|
||||
|
||||
// Update Expense Detail (if open and matches this expenseId)
|
||||
_safeControllerUpdate<ExpenseDetailController>(
|
||||
onFound: (controller) async {
|
||||
if (controller.expense.value?.id == expenseId) {
|
||||
@ -190,6 +197,11 @@ class NotificationActionHandler {
|
||||
}
|
||||
|
||||
static void _handleAttendanceUpdated(Map<String, dynamic> data) {
|
||||
if (!_isCurrentProject(data)) {
|
||||
_logger.i("ℹ️ Ignored attendance update from another project.");
|
||||
return;
|
||||
}
|
||||
|
||||
_safeControllerUpdate<AttendanceController>(
|
||||
onFound: (controller) => controller.refreshDataFromNotification(
|
||||
projectId: data['ProjectId'],
|
||||
@ -201,6 +213,11 @@ class NotificationActionHandler {
|
||||
|
||||
static void _handleTaskUpdated(Map<String, dynamic> data,
|
||||
{required bool isComment}) {
|
||||
if (!_isCurrentProject(data)) {
|
||||
_logger.i("ℹ️ Ignored task update from another project.");
|
||||
return;
|
||||
}
|
||||
|
||||
_safeControllerUpdate<DailyTaskController>(
|
||||
onFound: (controller) => controller.refreshTasksFromNotification(
|
||||
projectId: data['ProjectId'],
|
||||
@ -213,11 +230,15 @@ class NotificationActionHandler {
|
||||
|
||||
/// ---------------------- DOCUMENT HANDLER ----------------------
|
||||
static void _handleDocumentModified(Map<String, dynamic> data) {
|
||||
if (!_isCurrentProject(data)) {
|
||||
_logger.i("ℹ️ Ignored document update from another project.");
|
||||
return;
|
||||
}
|
||||
|
||||
String entityTypeId;
|
||||
String entityId;
|
||||
String? documentId = data['DocumentId'];
|
||||
|
||||
// Determine entity type and ID
|
||||
if (data['Keyword'] == 'Employee_Document_Modified') {
|
||||
entityTypeId = Permissions.employeeEntity;
|
||||
entityId = data['EmployeeId'] ?? '';
|
||||
@ -237,7 +258,6 @@ class NotificationActionHandler {
|
||||
_logger.i(
|
||||
"🔔 Document notification received: keyword=${data['Keyword']}, entityTypeId=$entityTypeId, entityId=$entityId, documentId=$documentId");
|
||||
|
||||
// Refresh Document List
|
||||
if (Get.isRegistered<DocumentController>()) {
|
||||
_safeControllerUpdate<DocumentController>(
|
||||
onFound: (controller) async {
|
||||
@ -255,11 +275,9 @@ class NotificationActionHandler {
|
||||
_logger.w('⚠️ DocumentController not registered, skipping list refresh.');
|
||||
}
|
||||
|
||||
// Refresh Document Details (if open)
|
||||
if (documentId != null && Get.isRegistered<DocumentDetailsController>()) {
|
||||
_safeControllerUpdate<DocumentDetailsController>(
|
||||
onFound: (controller) async {
|
||||
// Refresh details regardless of current document
|
||||
await controller.fetchDocumentDetails(documentId);
|
||||
_logger.i(
|
||||
"✅ DocumentDetailsController refreshed for Document $documentId");
|
||||
@ -276,13 +294,10 @@ class NotificationActionHandler {
|
||||
|
||||
/// ---------------------- DIRECTORY HANDLERS ----------------------
|
||||
static void _handleContactModified(Map<String, dynamic> data) {
|
||||
final contactId = data['ContactId'];
|
||||
|
||||
// Always refresh the contact list
|
||||
_safeControllerUpdate<DirectoryController>(
|
||||
onFound: (controller) {
|
||||
controller.fetchContacts();
|
||||
// If a specific contact is provided, refresh its notes as well
|
||||
final contactId = data['ContactId'];
|
||||
if (contactId != null) {
|
||||
controller.fetchCommentsForContact(contactId);
|
||||
}
|
||||
@ -293,7 +308,6 @@ class NotificationActionHandler {
|
||||
'✅ Directory contacts (and notes if applicable) refreshed from notification.',
|
||||
);
|
||||
|
||||
// Refresh notes globally as well
|
||||
_safeControllerUpdate<NotesController>(
|
||||
onFound: (controller) => controller.fetchNotes(),
|
||||
notFoundMessage: '⚠️ NotesController not found, cannot refresh notes.',
|
||||
@ -302,7 +316,6 @@ class NotificationActionHandler {
|
||||
}
|
||||
|
||||
static void _handleContactNoteModified(Map<String, dynamic> data) {
|
||||
// Refresh both contacts and notes when a note is modified
|
||||
_handleContactModified(data);
|
||||
}
|
||||
|
||||
@ -324,6 +337,11 @@ class NotificationActionHandler {
|
||||
|
||||
/// ---------------------- DASHBOARD HANDLER ----------------------
|
||||
static void _handleDashboardUpdate(Map<String, dynamic> data) {
|
||||
if (!_isCurrentProject(data)) {
|
||||
_logger.i("ℹ️ Ignored dashboard update from another project.");
|
||||
return;
|
||||
}
|
||||
|
||||
_safeControllerUpdate<DashboardController>(
|
||||
onFound: (controller) async {
|
||||
final type = data['type'] ?? '';
|
||||
@ -347,11 +365,9 @@ class NotificationActionHandler {
|
||||
controller.projectController.selectedProjectId.value;
|
||||
final projectIdsString = data['ProjectIds'] ?? '';
|
||||
|
||||
// Convert comma-separated string to List<String>
|
||||
final notificationProjectIds =
|
||||
projectIdsString.split(',').map((e) => e.trim()).toList();
|
||||
|
||||
// Refresh only if current project ID is in the list
|
||||
if (notificationProjectIds.contains(currentProjectId)) {
|
||||
await controller.fetchDashboardTeams(projectId: currentProjectId);
|
||||
}
|
||||
@ -375,6 +391,24 @@ class NotificationActionHandler {
|
||||
|
||||
/// ---------------------- UTILITY ----------------------
|
||||
|
||||
static bool _isCurrentProject(Map<String, dynamic> data) {
|
||||
try {
|
||||
final dashboard = Get.find<DashboardController>();
|
||||
final currentProjectId =
|
||||
dashboard.projectController.selectedProjectId.value;
|
||||
final notificationProjectId = data['ProjectId']?.toString();
|
||||
|
||||
if (notificationProjectId == null || notificationProjectId.isEmpty) {
|
||||
return true; // No project info → allow global refresh
|
||||
}
|
||||
|
||||
return notificationProjectId == currentProjectId;
|
||||
} catch (e) {
|
||||
_logger.w("⚠️ Could not verify project context: $e");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void _safeControllerUpdate<T>({
|
||||
required void Function(T controller) onFound,
|
||||
required String notFoundMessage,
|
||||
|
||||
@ -34,12 +34,12 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// Listen for future project selection changes
|
||||
// 🔁 Listen for project changes
|
||||
ever<String>(projectController.selectedProjectId, (projectId) async {
|
||||
if (projectId.isNotEmpty) await _loadData(projectId);
|
||||
});
|
||||
|
||||
// Load initial data
|
||||
// 🚀 Load initial data only once the screen is shown
|
||||
final projectId = projectController.selectedProjectId.value;
|
||||
if (projectId.isNotEmpty) _loadData(projectId);
|
||||
});
|
||||
@ -402,4 +402,13 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// 🧹 Clean up the controller when user leaves this screen
|
||||
if (Get.isRegistered<AttendanceController>()) {
|
||||
Get.delete<AttendanceController>();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user