From a11fc8005049476d7162eddfc28cb31db997b8ea Mon Sep 17 00:00:00 2001 From: Manish Date: Fri, 21 Nov 2025 17:36:56 +0530 Subject: [PATCH] UI enhancement --- .../assign_task_bottom_sheet .dart | 106 ++++++++---------- .../multiple_select_bottomsheet.dart | 13 ++- .../multiple_select_role_bottomsheet.dart | 49 ++------ 3 files changed, 63 insertions(+), 105 deletions(-) diff --git a/lib/model/dailyTaskPlanning/assign_task_bottom_sheet .dart b/lib/model/dailyTaskPlanning/assign_task_bottom_sheet .dart index 5191079..ce19774 100644 --- a/lib/model/dailyTaskPlanning/assign_task_bottom_sheet .dart +++ b/lib/model/dailyTaskPlanning/assign_task_bottom_sheet .dart @@ -164,47 +164,45 @@ class _AssignTaskBottomSheetState extends State { GestureDetector( onTap: _openEmployeeSelectionSheet, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), - decoration: BoxDecoration( - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(6), - ), - child: Row( - children: [ - const Icon(Icons.group, color: Colors.black54), - const SizedBox(width: 10), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(6), + ), + child: Row( + children: [ + const Icon(Icons.group, color: Colors.black54), + const SizedBox(width: 10), - // Expanded name area - Expanded( - child: Obx(() { - final count = controller.selectedEmployees.length; - if (count == 0) { - return MyText( - "Select team members", - color: Colors.grey.shade700, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ); - } + // Expanded name area + Expanded( + child: Obx(() { + final count = controller.selectedEmployees.length; + if (count == 0) { + return MyText( + "Select team members", + color: Colors.grey.shade700, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ); + } - final names = controller.selectedEmployees - .map((e) => e.name) - .join(", "); + final names = controller.selectedEmployees + .map((e) => e.name) + .join(", "); - return Text( - names, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: const TextStyle(fontSize: 14), - ); - }), - ), + return Text( + names, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontSize: 14), + ); + }), + ), - const Icon(Icons.arrow_drop_down, color: Colors.grey), - ], -) - - ), + const Icon(Icons.arrow_drop_down, color: Colors.grey), + ], + )), ), MySpacing.height(8), @@ -272,20 +270,14 @@ class _AssignTaskBottomSheetState extends State { spacing: 4, runSpacing: 4, children: controller.selectedEmployees.map((e) { - return Obx(() { - final isSelected = controller.uploadingStates[e.id]?.value ?? false; - if (!isSelected) return Container(); - - return Chip( - label: Text(e.name, style: const TextStyle(color: Colors.white)), - backgroundColor: const Color.fromARGB(255, 95, 132, 255), - deleteIcon: const Icon(Icons.close, color: Colors.white), - onDeleted: () { - controller.uploadingStates[e.id]?.value = false; - controller.updateSelectedEmployees(); - }, - ); - }); + return Chip( + label: Text(e.name, style: const TextStyle(color: Colors.white)), + backgroundColor: const Color.fromARGB(255, 95, 132, 255), + deleteIcon: const Icon(Icons.close, color: Colors.white), + onDeleted: () { + controller.selectedEmployees.remove(e); + }, + ); }).toList(), ); }); @@ -380,7 +372,6 @@ class _AssignTaskBottomSheetState extends State { color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), - child: MultipleSelectRoleBottomSheet( projectId: selectedProjectId!, organizationId: selectedOrganization?.id, @@ -396,16 +387,13 @@ class _AssignTaskBottomSheetState extends State { ); if (result != null) { - controller.selectedEmployees.assignAll(result); - controller.updateSelectedEmployees(); + controller.selectedEmployees + .assignAll(result); // RxList updates UI automatically } } void _onAssignTaskPressed() { - final selectedTeam = controller.uploadingStates.entries - .where((e) => e.value.value) - .map((e) => e.key) - .toList(); + final selectedTeam = controller.selectedEmployees; if (selectedTeam.isEmpty) { showAppSnackbar( @@ -449,7 +437,7 @@ class _AssignTaskBottomSheetState extends State { workItemId: widget.workItemId, plannedTask: target.toInt(), description: description, - taskTeam: selectedTeam, + taskTeam: selectedTeam.map((e) => e.id).toList(), // pass IDs assignmentDate: widget.assignmentDate, organizationId: selectedOrganization?.id, serviceId: selectedService?.id, diff --git a/lib/model/employees/multiple_select_bottomsheet.dart b/lib/model/employees/multiple_select_bottomsheet.dart index 984aeff..f3be00c 100644 --- a/lib/model/employees/multiple_select_bottomsheet.dart +++ b/lib/model/employees/multiple_select_bottomsheet.dart @@ -68,13 +68,18 @@ class _EmployeeSelectionBottomSheetState .toList(); // ------------------------------------------------------ - // 🔥 Auto-move selected employees to top + // Auto-move selected employees to top // ------------------------------------------------------ results.sort((a, b) { - final aSel = _selectedEmployees.contains(a) ? 0 : 1; - final bSel = _selectedEmployees.contains(b) ? 0 : 1; + if (widget.multipleSelection) { + // Only move selected employees to top in multi-select + final aSel = _selectedEmployees.contains(a) ? 0 : 1; + final bSel = _selectedEmployees.contains(b) ? 0 : 1; - if (aSel != bSel) return aSel.compareTo(bSel); + if (aSel != bSel) return aSel.compareTo(bSel); + } + + // Otherwise, keep original order (or alphabetically if needed) return a.name.toLowerCase().compareTo(b.name.toLowerCase()); }); diff --git a/lib/model/employees/multiple_select_role_bottomsheet.dart b/lib/model/employees/multiple_select_role_bottomsheet.dart index f7e5dff..a1f4951 100644 --- a/lib/model/employees/multiple_select_role_bottomsheet.dart +++ b/lib/model/employees/multiple_select_role_bottomsheet.dart @@ -63,7 +63,6 @@ class _MultipleSelectRoleBottomSheetState employees.where((emp) => emp.jobRoleID == widget.roleId).toList(); } - // Selected first employees.sort((a, b) { final aSel = _selected.any((e) => e.id == a.id) ? 0 : 1; final bSel = _selected.any((e) => e.id == b.id) ? 0 : 1; @@ -92,7 +91,6 @@ class _MultipleSelectRoleBottomSheetState ); } - // Selected on top _filtered.sort((a, b) { final aSel = _selected.any((e) => e.id == a.id) ? 0 : 1; final bSel = _selected.any((e) => e.id == b.id) ? 0 : 1; @@ -110,8 +108,8 @@ class _MultipleSelectRoleBottomSheetState _selected.add(emp); } } else { - _selected.assignAll([emp]); - Get.back(result: _selected); + // Single selection → return immediately + Get.back(result: [emp]); } _onSearch(_searchController.text.trim()); @@ -150,49 +148,17 @@ class _MultipleSelectRoleBottomSheetState ), ); - /// ⭐ NEW — Chips showing selected employees - Widget _selectedChips() { - return Obx(() { - if (_selected.isEmpty) return const SizedBox(); - - return Wrap( - spacing: 8, - runSpacing: 8, - children: _selected.map((emp) { - return Chip( - label: Text(emp.name), - deleteIcon: const Icon(Icons.close), - onDeleted: () { - _selected.remove(emp); - _onSearch(_searchController.text.trim()); - }, - backgroundColor: Colors.blue.shade50, - ); - }).toList(), - ); - }); - } - @override Widget build(BuildContext context) { return BaseBottomSheet( title: widget.title, onCancel: () => Get.back(), - onSubmit: () => Get.back(result: _selected), + onSubmit: () => Get.back(result: _selected.toList()), // Return plain list child: SizedBox( height: MediaQuery.of(context).size.height * 0.55, child: Column( children: [ _searchBar(), - - /// ⭐ Chips shown right below search bar - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: _selectedChips(), - ), - - const SizedBox(height: 6), - Expanded( child: Obx(() { if (_isLoading.value) { @@ -228,13 +194,12 @@ class _MultipleSelectRoleBottomSheetState fillColor: MaterialStateProperty.resolveWith((states) { if (states.contains(MaterialState.selected)) { - return Colors.blueAccent; // Selected color + return Colors.blueAccent; } - return Colors.white; // Unselected square color + return Colors.white; }), - checkColor: Colors.white, // Check mark color - side: const BorderSide( - color: Colors.grey), // Outline for unselected + checkColor: Colors.white, + side: const BorderSide(color: Colors.grey), ), contentPadding: const EdgeInsets.symmetric( horizontal: 4,