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 { class DashboardController extends GetxController {
// Observables // 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 RxBool isLoading = false.obs;
final RxString selectedRange = '7D'.obs; final RxString selectedRange = '7D'.obs;
final RxBool isChartView = true.obs; final RxBool isChartView = true.obs;
@ -15,33 +16,32 @@ class DashboardController extends GetxController {
// Inject the ProjectController // Inject the ProjectController
final ProjectController projectController = Get.find<ProjectController>(); final ProjectController projectController = Get.find<ProjectController>();
@override @override
void onInit() { void onInit() {
super.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) { if (projectController.selectedProjectId.value.isNotEmpty) {
// Fix: explicitly cast and use ever<T> with non-nullable type fetchRoleWiseAttendance();
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();
});
} }
// 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 get rangeDays => _getDaysFromRange(selectedRange.value);
int _getDaysFromRange(String range) { int _getDaysFromRange(String range) {
@ -69,10 +69,10 @@ class DashboardController extends GetxController {
} }
Future<void> fetchRoleWiseAttendance() async { Future<void> fetchRoleWiseAttendance() async {
final String? projectId = projectController.selectedProjectId?.value; final String projectId = projectController.selectedProjectId.value;
if (projectId == null || projectId.isEmpty) { if (projectId.isEmpty) {
log.w('Project ID is null or empty, skipping API call.'); log.w('Project ID is empty, skipping API call.');
return; return;
} }

View File

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

View File

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