done tags UX updates
This commit is contained in:
parent
a85bea54f8
commit
4daa412a87
@ -75,7 +75,7 @@ class AddServiceProjectJobController extends GetxController {
|
|||||||
assignees: assigneeIds.map((id) => {"id": id}).toList(),
|
assignees: assigneeIds.map((id) => {"id": id}).toList(),
|
||||||
startDate: startDate.value!,
|
startDate: startDate.value!,
|
||||||
dueDate: dueDate.value!,
|
dueDate: dueDate.value!,
|
||||||
tags: enteredTags.map((tag) => {"name": tag}).toList(),
|
tags: enteredTags.map((tag) => {"name": tag.trim()}).toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
|||||||
@ -204,11 +204,37 @@ class _AddServiceProjectJobBottomSheetState
|
|||||||
height: 48,
|
height: 48,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: controller.tagCtrl,
|
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) {
|
onFieldSubmitted: (v) {
|
||||||
final value = v.trim();
|
// also handle normal submit
|
||||||
if (value.isNotEmpty &&
|
final raw = v.trim();
|
||||||
!controller.enteredTags.contains(value)) {
|
if (raw.isEmpty) return;
|
||||||
controller.enteredTags.add(value);
|
|
||||||
|
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();
|
controller.tagCtrl.clear();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -201,7 +201,7 @@ class _JobsTabState extends State<JobsTab> {
|
|||||||
children: job.tags!.map((tag) {
|
children: job.tags!.map((tag) {
|
||||||
return Chip(
|
return Chip(
|
||||||
label: Text(
|
label: Text(
|
||||||
tag.name,
|
tag.name.replaceAll('_', ' '),
|
||||||
style:
|
style:
|
||||||
const TextStyle(fontSize: 12),
|
const TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -39,6 +39,10 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
final TextEditingController _dueDateController = TextEditingController();
|
final TextEditingController _dueDateController = TextEditingController();
|
||||||
final TextEditingController _tagTextController = 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<Assignee> _selectedAssignees = <Assignee>[].obs;
|
||||||
final RxList<Tag> _selectedTags = <Tag>[].obs;
|
final RxList<Tag> _selectedTags = <Tag>[].obs;
|
||||||
final RxBool isEditing = false.obs;
|
final RxBool isEditing = false.obs;
|
||||||
@ -47,21 +51,38 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
controller = Get.put(ServiceProjectDetailsController());
|
controller = Get.find<ServiceProjectDetailsController>();
|
||||||
controller.fetchJobDetail(widget.jobId).then((_) {
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
await controller.fetchJobDetail(widget.jobId);
|
||||||
|
|
||||||
final job = controller.jobDetail.value?.data;
|
final job = controller.jobDetail.value?.data;
|
||||||
if (job != null) {
|
if (job != null) {
|
||||||
_titleController.text = job.title ?? '';
|
_titleController.text = job.title ?? '';
|
||||||
_descriptionController.text = job.description ?? '';
|
_descriptionController.text = job.description ?? '';
|
||||||
|
|
||||||
_startDateController.text = DateTimeUtils.convertUtcToLocal(
|
_startDateController.text = DateTimeUtils.convertUtcToLocal(
|
||||||
job.startDate ?? DateTime.now().toIso8601String(),
|
job.startDate ?? DateTime.now().toIso8601String(),
|
||||||
format: "yyyy-MM-dd");
|
format: "yyyy-MM-dd");
|
||||||
|
|
||||||
_dueDateController.text = DateTimeUtils.convertUtcToLocal(
|
_dueDateController.text = DateTimeUtils.convertUtcToLocal(
|
||||||
job.dueDate ?? '',
|
job.dueDate ?? '',
|
||||||
format: "yyyy-MM-dd");
|
format: "yyyy-MM-dd");
|
||||||
|
|
||||||
_selectedAssignees.value = job.assignees ?? [];
|
_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(() {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,9 +188,19 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
showAppSnackbar(
|
showAppSnackbar(
|
||||||
title: "Success",
|
title: "Success",
|
||||||
message: "Job updated successfully",
|
message: "Job updated successfully",
|
||||||
type: SnackbarType.success);
|
type: SnackbarType.success,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Refresh detail screen
|
||||||
await controller.fetchJobDetail(widget.jobId);
|
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;
|
isEditing.value = false;
|
||||||
|
Navigator.pop(context); // optional if you want auto-close
|
||||||
} else {
|
} else {
|
||||||
showAppSnackbar(
|
showAppSnackbar(
|
||||||
title: "Error",
|
title: "Error",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user