done tags UX updates

This commit is contained in:
Manish 2025-11-24 10:16:41 +05:30
parent a85bea54f8
commit 4daa412a87
4 changed files with 71 additions and 14 deletions

View File

@ -75,7 +75,7 @@ class AddServiceProjectJobController extends GetxController {
assignees: assigneeIds.map((id) => {"id": id}).toList(),
startDate: startDate.value!,
dueDate: dueDate.value!,
tags: enteredTags.map((tag) => {"name": tag}).toList(),
tags: enteredTags.map((tag) => {"name": tag.trim()}).toList(),
);
isLoading.value = false;

View File

@ -204,11 +204,37 @@ class _AddServiceProjectJobBottomSheetState
height: 48,
child: TextFormField(
controller: controller.tagCtrl,
textInputAction: TextInputAction.done,
onEditingComplete: () {
final raw = controller.tagCtrl.text.trim();
if (raw.isEmpty) return;
final parts = raw
.split(',')
.map((s) => s.trim())
.where((s) => s.isNotEmpty);
for (final p in parts) {
if (!controller.enteredTags.contains(p)) {
controller.enteredTags.add(p);
}
}
controller.tagCtrl.clear();
},
onFieldSubmitted: (v) {
final value = v.trim();
if (value.isNotEmpty &&
!controller.enteredTags.contains(value)) {
controller.enteredTags.add(value);
// also handle normal submit
final raw = v.trim();
if (raw.isEmpty) return;
final parts = raw
.split(',')
.map((s) => s.trim())
.where((s) => s.isNotEmpty);
for (final p in parts) {
if (!controller.enteredTags.contains(p)) {
controller.enteredTags.add(p);
}
}
controller.tagCtrl.clear();
},

View File

@ -201,7 +201,7 @@ class _JobsTabState extends State<JobsTab> {
children: job.tags!.map((tag) {
return Chip(
label: Text(
tag.name,
tag.name.replaceAll('_', ' '),
style:
const TextStyle(fontSize: 12),
),
@ -318,7 +318,7 @@ class _JobsTabState extends State<JobsTab> {
final success =
await ApiService.editServiceProjectJobApi(
jobId: job.id ,
jobId: job.id,
operations: operations,
);

View File

@ -39,6 +39,10 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
final TextEditingController _dueDateController = TextEditingController();
final TextEditingController _tagTextController = TextEditingController();
final RxList<String> tags = <String>[].obs; // For showing/editing tag chips
final TextEditingController tagController =
TextEditingController(); // For tag input
final RxList<Assignee> _selectedAssignees = <Assignee>[].obs;
final RxList<Tag> _selectedTags = <Tag>[].obs;
final RxBool isEditing = false.obs;
@ -47,21 +51,38 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
@override
void initState() {
super.initState();
controller = Get.put(ServiceProjectDetailsController());
controller.fetchJobDetail(widget.jobId).then((_) {
controller = Get.find<ServiceProjectDetailsController>();
WidgetsBinding.instance.addPostFrameCallback((_) async {
await controller.fetchJobDetail(widget.jobId);
final job = controller.jobDetail.value?.data;
if (job != null) {
_titleController.text = job.title ?? '';
_descriptionController.text = job.description ?? '';
_startDateController.text = DateTimeUtils.convertUtcToLocal(
job.startDate ?? DateTime.now().toIso8601String(),
format: "yyyy-MM-dd");
_dueDateController.text = DateTimeUtils.convertUtcToLocal(
job.dueDate ?? '',
format: "yyyy-MM-dd");
_selectedAssignees.value = job.assignees ?? [];
_selectedTags.value = job.tags ?? [];
// ---------- TAG FIX ----------
final tagList = job.tags ?? [];
final cleanedTags = tagList
.map((t) => (t.name ?? "").replaceAll("_", " ").trim())
.toList();
tags.assignAll(cleanedTags);
tagController.clear();
}
setState(() {});
});
}
@ -165,11 +186,21 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
if (success) {
showAppSnackbar(
title: "Success",
message: "Job updated successfully",
type: SnackbarType.success);
title: "Success",
message: "Job updated successfully",
type: SnackbarType.success,
);
/// Refresh detail screen
await controller.fetchJobDetail(widget.jobId);
/// 🔥 Auto refresh job list UI (main Service Project Details screen)
if (Get.isRegistered<ServiceProjectDetailsController>()) {
await Get.find<ServiceProjectDetailsController>().refreshJobsAfterAdd();
}
isEditing.value = false;
Navigator.pop(context); // optional if you want auto-close
} else {
showAppSnackbar(
title: "Error",