feat: Improve project ID handling and enhance attendance chart data observation

This commit is contained in:
Vaibhav Surve 2025-06-23 15:36:40 +05:30
parent 099edd3884
commit f7fcad2992
3 changed files with 42 additions and 40 deletions

View File

@ -7,7 +7,8 @@ final Logger log = Logger();
class DashboardController extends GetxController {
// Observables
final RxList<Map<String, dynamic>> roleWiseData = <Map<String, dynamic>>[].obs;
final RxList<Map<String, dynamic>> roleWiseData =
<Map<String, dynamic>>[].obs;
final RxBool isLoading = false.obs;
final RxString selectedRange = '7D'.obs;
final RxBool isChartView = true.obs;
@ -15,33 +16,32 @@ class DashboardController extends GetxController {
// Inject the ProjectController
final ProjectController projectController = Get.find<ProjectController>();
@override
void onInit() {
super.onInit();
@override
void onInit() {
super.onInit();
final selectedProjectIdRx = projectController.selectedProjectId;
// Log to verify order of controller initialization
log.i('DashboardController initialized with project ID: ${projectController.selectedProjectId.value}');
if (selectedProjectIdRx != null) {
// Fix: explicitly cast and use ever<T> with non-nullable type
ever<String>(selectedProjectIdRx, (id) {
if (id.isNotEmpty) {
fetchRoleWiseAttendance();
}
});
// Initial load if already has value
if (selectedProjectIdRx.value.isNotEmpty) {
fetchRoleWiseAttendance();
}
} else {
log.w('selectedProjectId observable is null in ProjectController.');
}
ever(selectedRange, (_) {
fetchRoleWiseAttendance();
});
if (projectController.selectedProjectId.value.isNotEmpty) {
fetchRoleWiseAttendance();
}
// React to project change
ever<String>(projectController.selectedProjectId, (id) {
if (id.isNotEmpty) {
log.i('Project changed to $id, fetching attendance');
fetchRoleWiseAttendance();
}
});
// React to range change
ever(selectedRange, (_) {
fetchRoleWiseAttendance();
});
}
int get rangeDays => _getDaysFromRange(selectedRange.value);
int _getDaysFromRange(String range) {
@ -69,10 +69,10 @@ class DashboardController extends GetxController {
}
Future<void> fetchRoleWiseAttendance() async {
final String? projectId = projectController.selectedProjectId?.value;
final String projectId = projectController.selectedProjectId.value;
if (projectId == null || projectId.isEmpty) {
log.w('Project ID is null or empty, skipping API call.');
if (projectId.isEmpty) {
log.w('Project ID is empty, skipping API call.');
return;
}

View File

@ -8,7 +8,7 @@ final Logger log = Logger();
class ProjectController extends GetxController {
RxList<GlobalProjectModel> projects = <GlobalProjectModel>[].obs;
RxString? selectedProjectId;
RxString selectedProjectId = ''.obs;
RxBool isProjectListExpanded = false.obs;
RxBool isProjectSelectionExpanded = false.obs;
@ -17,9 +17,9 @@ class ProjectController extends GetxController {
RxBool isLoadingProjects = true.obs;
RxMap<String, RxBool> uploadingStates = <String, RxBool>{}.obs;
GlobalProjectModel? get selectedProject {
if (selectedProjectId == null || selectedProjectId!.value.isEmpty)
return null;
return projects.firstWhereOrNull((p) => p.id == selectedProjectId!.value);
if (selectedProjectId.value.isEmpty) return null;
return projects.firstWhereOrNull((p) => p.id == selectedProjectId.value);
}
@override
@ -30,7 +30,8 @@ class ProjectController extends GetxController {
void clearProjects() {
projects.clear();
selectedProjectId = null;
selectedProjectId.value = '';
isProjectSelectionExpanded.value = false;
isProjectListExpanded.value = false;
isProjectDropdownExpanded.value = false;
@ -54,11 +55,10 @@ class ProjectController extends GetxController {
String? savedId = LocalStorage.getString('selectedProjectId');
if (savedId != null && projects.any((p) => p.id == savedId)) {
selectedProjectId = RxString(savedId);
selectedProjectId.value = savedId; // update value only
} else {
selectedProjectId = RxString(projects.first.id.toString());
LocalStorage.saveString(
'selectedProjectId', projects.first.id.toString());
selectedProjectId.value = projects.first.id.toString(); //
LocalStorage.saveString('selectedProjectId', selectedProjectId.value);
}
isProjectSelectionExpanded.value = false;
@ -73,10 +73,9 @@ class ProjectController extends GetxController {
}
Future<void> updateSelectedProject(String projectId) async {
selectedProjectId?.value = projectId;
selectedProjectId.value = projectId;
await LocalStorage.saveString('selectedProjectId', projectId);
update([
'selected_project'
]);
update(['selected_project']);
}
}

View File

@ -62,6 +62,7 @@ class AttendanceDashboardChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Obx(() {
// Now this observes `controller.roleWiseData`, `isLoading`, `isChartView`, etc.
final isChartView = controller.isChartView.value;
final selectedRange = controller.selectedRange.value;
final isLoading = controller.isLoading.value;
@ -226,6 +227,8 @@ class AttendanceDashboardChart extends StatelessWidget {
name: role,
legendIconType: LegendIconType.circle,
dataLabelSettings: const DataLabelSettings(isVisible: true),
dataLabelMapper: (d, _) =>
d['present'] == 0 ? '' : d['present'].toString(),
color: _getRoleColor(role),
);
}).toList(),