UI enhancement

This commit is contained in:
Manish 2025-11-21 17:36:56 +05:30
parent 84395765fd
commit 19e6979c0e
3 changed files with 63 additions and 105 deletions

View File

@ -164,47 +164,45 @@ class _AssignTaskBottomSheetState extends State<AssignTaskBottomSheet> {
GestureDetector( GestureDetector(
onTap: _openEmployeeSelectionSheet, onTap: _openEmployeeSelectionSheet,
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300), border: Border.all(color: Colors.grey.shade300),
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
), ),
child: Row( child: Row(
children: [ children: [
const Icon(Icons.group, color: Colors.black54), const Icon(Icons.group, color: Colors.black54),
const SizedBox(width: 10), const SizedBox(width: 10),
// Expanded name area // Expanded name area
Expanded( Expanded(
child: Obx(() { child: Obx(() {
final count = controller.selectedEmployees.length; final count = controller.selectedEmployees.length;
if (count == 0) { if (count == 0) {
return MyText( return MyText(
"Select team members", "Select team members",
color: Colors.grey.shade700, color: Colors.grey.shade700,
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
); );
} }
final names = controller.selectedEmployees final names = controller.selectedEmployees
.map((e) => e.name) .map((e) => e.name)
.join(", "); .join(", ");
return Text( return Text(
names, names,
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14), 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), MySpacing.height(8),
@ -272,20 +270,14 @@ class _AssignTaskBottomSheetState extends State<AssignTaskBottomSheet> {
spacing: 4, spacing: 4,
runSpacing: 4, runSpacing: 4,
children: controller.selectedEmployees.map((e) { children: controller.selectedEmployees.map((e) {
return Obx(() { return Chip(
final isSelected = controller.uploadingStates[e.id]?.value ?? false; label: Text(e.name, style: const TextStyle(color: Colors.white)),
if (!isSelected) return Container(); backgroundColor: const Color.fromARGB(255, 95, 132, 255),
deleteIcon: const Icon(Icons.close, color: Colors.white),
return Chip( onDeleted: () {
label: Text(e.name, style: const TextStyle(color: Colors.white)), controller.selectedEmployees.remove(e);
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();
},
);
});
}).toList(), }).toList(),
); );
}); });
@ -380,7 +372,6 @@ class _AssignTaskBottomSheetState extends State<AssignTaskBottomSheet> {
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)), borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
), ),
child: MultipleSelectRoleBottomSheet( child: MultipleSelectRoleBottomSheet(
projectId: selectedProjectId!, projectId: selectedProjectId!,
organizationId: selectedOrganization?.id, organizationId: selectedOrganization?.id,
@ -396,16 +387,13 @@ class _AssignTaskBottomSheetState extends State<AssignTaskBottomSheet> {
); );
if (result != null) { if (result != null) {
controller.selectedEmployees.assignAll(result); controller.selectedEmployees
controller.updateSelectedEmployees(); .assignAll(result); // RxList updates UI automatically
} }
} }
void _onAssignTaskPressed() { void _onAssignTaskPressed() {
final selectedTeam = controller.uploadingStates.entries final selectedTeam = controller.selectedEmployees;
.where((e) => e.value.value)
.map((e) => e.key)
.toList();
if (selectedTeam.isEmpty) { if (selectedTeam.isEmpty) {
showAppSnackbar( showAppSnackbar(
@ -449,7 +437,7 @@ class _AssignTaskBottomSheetState extends State<AssignTaskBottomSheet> {
workItemId: widget.workItemId, workItemId: widget.workItemId,
plannedTask: target.toInt(), plannedTask: target.toInt(),
description: description, description: description,
taskTeam: selectedTeam, taskTeam: selectedTeam.map((e) => e.id).toList(), // pass IDs
assignmentDate: widget.assignmentDate, assignmentDate: widget.assignmentDate,
organizationId: selectedOrganization?.id, organizationId: selectedOrganization?.id,
serviceId: selectedService?.id, serviceId: selectedService?.id,

View File

@ -68,13 +68,18 @@ class _EmployeeSelectionBottomSheetState
.toList(); .toList();
// ------------------------------------------------------ // ------------------------------------------------------
// 🔥 Auto-move selected employees to top // Auto-move selected employees to top
// ------------------------------------------------------ // ------------------------------------------------------
results.sort((a, b) { results.sort((a, b) {
final aSel = _selectedEmployees.contains(a) ? 0 : 1; if (widget.multipleSelection) {
final bSel = _selectedEmployees.contains(b) ? 0 : 1; // 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()); return a.name.toLowerCase().compareTo(b.name.toLowerCase());
}); });

View File

@ -63,7 +63,6 @@ class _MultipleSelectRoleBottomSheetState
employees.where((emp) => emp.jobRoleID == widget.roleId).toList(); employees.where((emp) => emp.jobRoleID == widget.roleId).toList();
} }
// Selected first
employees.sort((a, b) { employees.sort((a, b) {
final aSel = _selected.any((e) => e.id == a.id) ? 0 : 1; final aSel = _selected.any((e) => e.id == a.id) ? 0 : 1;
final bSel = _selected.any((e) => e.id == b.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) { _filtered.sort((a, b) {
final aSel = _selected.any((e) => e.id == a.id) ? 0 : 1; final aSel = _selected.any((e) => e.id == a.id) ? 0 : 1;
final bSel = _selected.any((e) => e.id == b.id) ? 0 : 1; final bSel = _selected.any((e) => e.id == b.id) ? 0 : 1;
@ -110,8 +108,8 @@ class _MultipleSelectRoleBottomSheetState
_selected.add(emp); _selected.add(emp);
} }
} else { } else {
_selected.assignAll([emp]); // Single selection return immediately
Get.back(result: _selected); Get.back(result: [emp]);
} }
_onSearch(_searchController.text.trim()); _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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseBottomSheet( return BaseBottomSheet(
title: widget.title, title: widget.title,
onCancel: () => Get.back(), onCancel: () => Get.back(),
onSubmit: () => Get.back(result: _selected), onSubmit: () => Get.back(result: _selected.toList()), // Return plain list
child: SizedBox( child: SizedBox(
height: MediaQuery.of(context).size.height * 0.55, height: MediaQuery.of(context).size.height * 0.55,
child: Column( child: Column(
children: [ children: [
_searchBar(), _searchBar(),
/// Chips shown right below search bar
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: _selectedChips(),
),
const SizedBox(height: 6),
Expanded( Expanded(
child: Obx(() { child: Obx(() {
if (_isLoading.value) { if (_isLoading.value) {
@ -228,13 +194,12 @@ class _MultipleSelectRoleBottomSheetState
fillColor: fillColor:
MaterialStateProperty.resolveWith<Color>((states) { MaterialStateProperty.resolveWith<Color>((states) {
if (states.contains(MaterialState.selected)) { 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 checkColor: Colors.white,
side: const BorderSide( side: const BorderSide(color: Colors.grey),
color: Colors.grey), // Outline for unselected
), ),
contentPadding: const EdgeInsets.symmetric( contentPadding: const EdgeInsets.symmetric(
horizontal: 4, horizontal: 4,