feat: update JobDetailsResponse and JobData models to support nullable fields and improve JSON parsing
This commit is contained in:
parent
02ef996753
commit
c44d10d35a
@ -1,91 +1,95 @@
|
|||||||
class JobDetailsResponse {
|
class JobDetailsResponse {
|
||||||
final bool success;
|
final bool? success;
|
||||||
final String message;
|
final String? message;
|
||||||
final JobData? data;
|
final JobData? data;
|
||||||
final dynamic errors;
|
final dynamic errors;
|
||||||
final int statusCode;
|
final int? statusCode;
|
||||||
final String timestamp;
|
final String? timestamp;
|
||||||
|
|
||||||
JobDetailsResponse({
|
JobDetailsResponse({
|
||||||
required this.success,
|
this.success,
|
||||||
required this.message,
|
this.message,
|
||||||
this.data,
|
this.data,
|
||||||
this.errors,
|
this.errors,
|
||||||
required this.statusCode,
|
this.statusCode,
|
||||||
required this.timestamp,
|
this.timestamp,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory JobDetailsResponse.fromJson(Map<String, dynamic> json) {
|
factory JobDetailsResponse.fromJson(Map<String, dynamic>? json) {
|
||||||
|
if (json == null) return JobDetailsResponse();
|
||||||
|
|
||||||
return JobDetailsResponse(
|
return JobDetailsResponse(
|
||||||
success: json['success'] as bool,
|
success: json['success'] as bool?,
|
||||||
message: json['message'] as String,
|
message: json['message'] as String?,
|
||||||
data: json['data'] != null ? JobData.fromJson(json['data']) : null,
|
data: json['data'] != null ? JobData.fromJson(json['data']) : null,
|
||||||
errors: json['errors'],
|
errors: json['errors'],
|
||||||
statusCode: json['statusCode'] as int,
|
statusCode: json['statusCode'] as int?,
|
||||||
timestamp: json['timestamp'] as String,
|
timestamp: json['timestamp'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class JobData {
|
class JobData {
|
||||||
final String id;
|
final String? id;
|
||||||
final String title;
|
final String? title;
|
||||||
final String description;
|
final String? description;
|
||||||
final String jobTicketUId;
|
final String? jobTicketUId;
|
||||||
final Project project;
|
final Project? project;
|
||||||
final List<Assignee> assignees;
|
final List<Assignee>? assignees;
|
||||||
final Status status;
|
final Status? status;
|
||||||
final String startDate;
|
final String? startDate;
|
||||||
final String dueDate;
|
final String? dueDate;
|
||||||
final bool isActive;
|
final bool? isActive;
|
||||||
final dynamic taggingAction;
|
final dynamic taggingAction;
|
||||||
final String? attendanceId;
|
final String? attendanceId;
|
||||||
final int? nextTaggingAction;
|
final int? nextTaggingAction;
|
||||||
final String createdAt;
|
final String? createdAt;
|
||||||
final User createdBy;
|
final User? createdBy;
|
||||||
final List<Tag> tags;
|
final List<Tag>? tags;
|
||||||
final List<UpdateLog> updateLogs;
|
final List<UpdateLog>? updateLogs;
|
||||||
|
|
||||||
JobData({
|
JobData({
|
||||||
required this.id,
|
this.id,
|
||||||
required this.title,
|
this.title,
|
||||||
required this.description,
|
this.description,
|
||||||
required this.jobTicketUId,
|
this.jobTicketUId,
|
||||||
required this.project,
|
this.project,
|
||||||
required this.assignees,
|
this.assignees,
|
||||||
required this.status,
|
this.status,
|
||||||
required this.startDate,
|
this.startDate,
|
||||||
required this.dueDate,
|
this.dueDate,
|
||||||
required this.isActive,
|
this.isActive,
|
||||||
this.taggingAction,
|
this.taggingAction,
|
||||||
this.attendanceId,
|
this.attendanceId,
|
||||||
this.nextTaggingAction,
|
this.nextTaggingAction,
|
||||||
required this.createdAt,
|
this.createdAt,
|
||||||
required this.createdBy,
|
this.createdBy,
|
||||||
required this.tags,
|
this.tags,
|
||||||
required this.updateLogs,
|
this.updateLogs,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory JobData.fromJson(Map<String, dynamic> json) {
|
factory JobData.fromJson(Map<String, dynamic>? json) {
|
||||||
|
if (json == null) return JobData();
|
||||||
|
|
||||||
return JobData(
|
return JobData(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String?,
|
||||||
title: json['title'] as String,
|
title: json['title'] as String?,
|
||||||
description: json['description'] as String,
|
description: json['description'] as String?,
|
||||||
jobTicketUId: json['jobTicketUId'] as String,
|
jobTicketUId: json['jobTicketUId'] as String?,
|
||||||
project: Project.fromJson(json['project']),
|
project: json['project'] != null ? Project.fromJson(json['project']) : null,
|
||||||
assignees: (json['assignees'] as List<dynamic>?)
|
assignees: (json['assignees'] as List<dynamic>?)
|
||||||
?.map((e) => Assignee.fromJson(e))
|
?.map((e) => Assignee.fromJson(e))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
[],
|
[],
|
||||||
status: Status.fromJson(json['status']),
|
status: json['status'] != null ? Status.fromJson(json['status']) : null,
|
||||||
startDate: json['startDate'] as String,
|
startDate: json['startDate'] as String?,
|
||||||
dueDate: json['dueDate'] as String,
|
dueDate: json['dueDate'] as String?,
|
||||||
isActive: json['isActive'] as bool,
|
isActive: json['isActive'] as bool?,
|
||||||
taggingAction: json['taggingAction'],
|
taggingAction: json['taggingAction'],
|
||||||
attendanceId: json['attendanceId'] as String?,
|
attendanceId: json['attendanceId'] as String?,
|
||||||
nextTaggingAction: json['nextTaggingAction'] as int?,
|
nextTaggingAction: json['nextTaggingAction'] as int?,
|
||||||
createdAt: json['createdAt'] as String,
|
createdAt: json['createdAt'] as String?,
|
||||||
createdBy: User.fromJson(json['createdBy']),
|
createdBy: json['createdBy'] != null ? User.fromJson(json['createdBy']) : null,
|
||||||
tags: (json['tags'] as List<dynamic>?)
|
tags: (json['tags'] as List<dynamic>?)
|
||||||
?.map((e) => Tag.fromJson(e))
|
?.map((e) => Tag.fromJson(e))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
@ -99,120 +103,128 @@ class JobData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Project {
|
class Project {
|
||||||
final String id;
|
final String? id;
|
||||||
final String name;
|
final String? name;
|
||||||
final String shortName;
|
final String? shortName;
|
||||||
final String assignedDate;
|
final String? assignedDate;
|
||||||
final String contactName;
|
final String? contactName;
|
||||||
final String contactPhone;
|
final String? contactPhone;
|
||||||
final String contactEmail;
|
final String? contactEmail;
|
||||||
|
|
||||||
Project({
|
Project({
|
||||||
required this.id,
|
this.id,
|
||||||
required this.name,
|
this.name,
|
||||||
required this.shortName,
|
this.shortName,
|
||||||
required this.assignedDate,
|
this.assignedDate,
|
||||||
required this.contactName,
|
this.contactName,
|
||||||
required this.contactPhone,
|
this.contactPhone,
|
||||||
required this.contactEmail,
|
this.contactEmail,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Project.fromJson(Map<String, dynamic> json) {
|
factory Project.fromJson(Map<String, dynamic>? json) {
|
||||||
|
if (json == null) return Project();
|
||||||
|
|
||||||
return Project(
|
return Project(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String?,
|
||||||
name: json['name'] as String,
|
name: json['name'] as String?,
|
||||||
shortName: json['shortName'] as String,
|
shortName: json['shortName'] as String?,
|
||||||
assignedDate: json['assignedDate'] as String,
|
assignedDate: json['assignedDate'] as String?,
|
||||||
contactName: json['contactName'] as String,
|
contactName: json['contactName'] as String?,
|
||||||
contactPhone: json['contactPhone'] as String,
|
contactPhone: json['contactPhone'] as String?,
|
||||||
contactEmail: json['contactEmail'] as String,
|
contactEmail: json['contactEmail'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Assignee {
|
class Assignee {
|
||||||
final String id;
|
final String? id;
|
||||||
final String firstName;
|
final String? firstName;
|
||||||
final String lastName;
|
final String? lastName;
|
||||||
final String? email;
|
final String? email;
|
||||||
final String? photo;
|
final String? photo;
|
||||||
final String jobRoleId;
|
final String? jobRoleId;
|
||||||
final String jobRoleName;
|
final String? jobRoleName;
|
||||||
|
|
||||||
Assignee({
|
Assignee({
|
||||||
required this.id,
|
this.id,
|
||||||
required this.firstName,
|
this.firstName,
|
||||||
required this.lastName,
|
this.lastName,
|
||||||
this.email,
|
this.email,
|
||||||
this.photo,
|
this.photo,
|
||||||
required this.jobRoleId,
|
this.jobRoleId,
|
||||||
required this.jobRoleName,
|
this.jobRoleName,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Assignee.fromJson(Map<String, dynamic> json) {
|
factory Assignee.fromJson(Map<String, dynamic>? json) {
|
||||||
|
if (json == null) return Assignee();
|
||||||
|
|
||||||
return Assignee(
|
return Assignee(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String?,
|
||||||
firstName: json['firstName'] as String,
|
firstName: json['firstName'] as String?,
|
||||||
lastName: json['lastName'] as String,
|
lastName: json['lastName'] as String?,
|
||||||
email: json['email'] as String?,
|
email: json['email'] as String?,
|
||||||
photo: json['photo'] as String?,
|
photo: json['photo'] as String?,
|
||||||
jobRoleId: json['jobRoleId'] as String,
|
jobRoleId: json['jobRoleId'] as String?,
|
||||||
jobRoleName: json['jobRoleName'] as String,
|
jobRoleName: json['jobRoleName'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Status {
|
class Status {
|
||||||
final String id;
|
final String? id;
|
||||||
final String name;
|
final String? name;
|
||||||
final String displayName;
|
final String? displayName;
|
||||||
final int level;
|
final int? level;
|
||||||
|
|
||||||
Status({
|
Status({
|
||||||
required this.id,
|
this.id,
|
||||||
required this.name,
|
this.name,
|
||||||
required this.displayName,
|
this.displayName,
|
||||||
required this.level,
|
this.level,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Status.fromJson(Map<String, dynamic> json) {
|
factory Status.fromJson(Map<String, dynamic>? json) {
|
||||||
|
if (json == null) return Status();
|
||||||
|
|
||||||
return Status(
|
return Status(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String?,
|
||||||
name: json['name'] as String,
|
name: json['name'] as String?,
|
||||||
displayName: json['displayName'] as String,
|
displayName: json['displayName'] as String?,
|
||||||
level: json['level'] as int,
|
level: json['level'] as int?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class User {
|
class User {
|
||||||
final String id;
|
final String? id;
|
||||||
final String firstName;
|
final String? firstName;
|
||||||
final String lastName;
|
final String? lastName;
|
||||||
final String? email;
|
final String? email;
|
||||||
final String? photo;
|
final String? photo;
|
||||||
final String jobRoleId;
|
final String? jobRoleId;
|
||||||
final String jobRoleName;
|
final String? jobRoleName;
|
||||||
|
|
||||||
User({
|
User({
|
||||||
required this.id,
|
this.id,
|
||||||
required this.firstName,
|
this.firstName,
|
||||||
required this.lastName,
|
this.lastName,
|
||||||
this.email,
|
this.email,
|
||||||
this.photo,
|
this.photo,
|
||||||
required this.jobRoleId,
|
this.jobRoleId,
|
||||||
required this.jobRoleName,
|
this.jobRoleName,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory User.fromJson(Map<String, dynamic> json) {
|
factory User.fromJson(Map<String, dynamic>? json) {
|
||||||
|
if (json == null) return User();
|
||||||
|
|
||||||
return User(
|
return User(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String?,
|
||||||
firstName: json['firstName'] as String,
|
firstName: json['firstName'] as String?,
|
||||||
lastName: json['lastName'] as String,
|
lastName: json['lastName'] as String?,
|
||||||
email: json['email'] as String?,
|
email: json['email'] as String?,
|
||||||
photo: json['photo'] as String?,
|
photo: json['photo'] as String?,
|
||||||
jobRoleId: json['jobRoleId'] as String,
|
jobRoleId: json['jobRoleId'] as String?,
|
||||||
jobRoleName: json['jobRoleName'] as String,
|
jobRoleName: json['jobRoleName'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,7 +235,9 @@ class Tag {
|
|||||||
|
|
||||||
Tag({this.id, this.name});
|
Tag({this.id, this.name});
|
||||||
|
|
||||||
factory Tag.fromJson(Map<String, dynamic> json) {
|
factory Tag.fromJson(Map<String, dynamic>? json) {
|
||||||
|
if (json == null) return Tag();
|
||||||
|
|
||||||
return Tag(
|
return Tag(
|
||||||
id: json['id'] as String?,
|
id: json['id'] as String?,
|
||||||
name: json['name'] as String?,
|
name: json['name'] as String?,
|
||||||
@ -232,27 +246,29 @@ class Tag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class UpdateLog {
|
class UpdateLog {
|
||||||
final String id;
|
final String? id;
|
||||||
final Status? status;
|
final Status? status;
|
||||||
final Status nextStatus;
|
final Status? nextStatus;
|
||||||
final String comment;
|
final String? comment;
|
||||||
final User updatedBy;
|
final User? updatedBy;
|
||||||
|
|
||||||
UpdateLog({
|
UpdateLog({
|
||||||
required this.id,
|
this.id,
|
||||||
this.status,
|
this.status,
|
||||||
required this.nextStatus,
|
this.nextStatus,
|
||||||
required this.comment,
|
this.comment,
|
||||||
required this.updatedBy,
|
this.updatedBy,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory UpdateLog.fromJson(Map<String, dynamic> json) {
|
factory UpdateLog.fromJson(Map<String, dynamic>? json) {
|
||||||
|
if (json == null) return UpdateLog();
|
||||||
|
|
||||||
return UpdateLog(
|
return UpdateLog(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String?,
|
||||||
status: json['status'] != null ? Status.fromJson(json['status']) : null,
|
status: json['status'] != null ? Status.fromJson(json['status']) : null,
|
||||||
nextStatus: Status.fromJson(json['nextStatus']),
|
nextStatus: json['nextStatus'] != null ? Status.fromJson(json['nextStatus']) : null,
|
||||||
comment: json['comment'] as String,
|
comment: json['comment'] as String?,
|
||||||
updatedBy: User.fromJson(json['updatedBy']),
|
updatedBy: json['updatedBy'] != null ? User.fromJson(json['updatedBy']) : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,15 +50,16 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
controller.fetchJobDetail(widget.jobId).then((_) {
|
controller.fetchJobDetail(widget.jobId).then((_) {
|
||||||
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,
|
job.startDate ?? DateTime.now().toIso8601String(),
|
||||||
format: "yyyy-MM-dd");
|
format: "yyyy-MM-dd");
|
||||||
_dueDateController.text =
|
_dueDateController.text = DateTimeUtils.convertUtcToLocal(
|
||||||
DateTimeUtils.convertUtcToLocal(job.dueDate, format: "yyyy-MM-dd");
|
job.dueDate ?? '',
|
||||||
_selectedAssignees.value = job.assignees;
|
format: "yyyy-MM-dd");
|
||||||
_selectedTags.value = job.tags;
|
_selectedAssignees.value = job.assignees ?? [];
|
||||||
|
_selectedTags.value = job.tags ?? [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -114,14 +115,14 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final originalAssignees = job.assignees;
|
final originalAssignees = job.assignees;
|
||||||
final assigneesPayload = originalAssignees.map((a) {
|
final assigneesPayload = originalAssignees?.map((a) {
|
||||||
final isSelected = _selectedAssignees.any((s) => s.id == a.id);
|
final isSelected = _selectedAssignees.any((s) => s.id == a.id);
|
||||||
return {"employeeId": a.id, "isActive": isSelected};
|
return {"employeeId": a.id, "isActive": isSelected};
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
for (var s in _selectedAssignees) {
|
for (var s in _selectedAssignees) {
|
||||||
if (!originalAssignees.any((a) => a.id == s.id)) {
|
if (!(originalAssignees?.any((a) => a.id == s.id) ?? false)) {
|
||||||
assigneesPayload.add({"employeeId": s.id, "isActive": true});
|
assigneesPayload?.add({"employeeId": s.id, "isActive": true});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +130,7 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
{"op": "replace", "path": "/assignees", "value": assigneesPayload});
|
{"op": "replace", "path": "/assignees", "value": assigneesPayload});
|
||||||
|
|
||||||
final originalTags = job.tags;
|
final originalTags = job.tags;
|
||||||
final replaceTagsPayload = originalTags.map((t) {
|
final replaceTagsPayload = originalTags?.map((t) {
|
||||||
final isSelected = _selectedTags.any((s) => s.id == t.id);
|
final isSelected = _selectedTags.any((s) => s.id == t.id);
|
||||||
return {"id": t.id, "name": t.name, "isActive": isSelected};
|
return {"id": t.id, "name": t.name, "isActive": isSelected};
|
||||||
}).toList();
|
}).toList();
|
||||||
@ -139,7 +140,7 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
.map((t) => {"name": t.name, "isActive": true})
|
.map((t) => {"name": t.name, "isActive": true})
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
if (replaceTagsPayload.isNotEmpty) {
|
if ((replaceTagsPayload?.isNotEmpty ?? false)) {
|
||||||
operations
|
operations
|
||||||
.add({"op": "replace", "path": "/tags", "value": replaceTagsPayload});
|
.add({"op": "replace", "path": "/tags", "value": replaceTagsPayload});
|
||||||
}
|
}
|
||||||
@ -157,7 +158,7 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final success = await ApiService.editServiceProjectJobApi(
|
final success = await ApiService.editServiceProjectJobApi(
|
||||||
jobId: job.id,
|
jobId: job.id ?? "",
|
||||||
operations: operations,
|
operations: operations,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -207,7 +208,7 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await controller.updateJobAttendance(
|
await controller.updateJobAttendance(
|
||||||
jobId: job.id,
|
jobId: job.id ?? "",
|
||||||
action: action == 0 ? 0 : 1,
|
action: action == 0 ? 0 : 1,
|
||||||
comment: comment,
|
comment: comment,
|
||||||
attachment: attachmentFile,
|
attachment: attachmentFile,
|
||||||
@ -352,14 +353,14 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
onTap: () async {
|
onTap: () async {
|
||||||
final initiallySelected = assignees.map<EmployeeModel>((a) {
|
final initiallySelected = assignees.map<EmployeeModel>((a) {
|
||||||
return EmployeeModel(
|
return EmployeeModel(
|
||||||
id: a.id,
|
id: a.id ?? '',
|
||||||
employeeId: a.id,
|
employeeId: a.id ?? '',
|
||||||
firstName: a.firstName,
|
firstName: a.firstName ?? '',
|
||||||
lastName: a.lastName,
|
lastName: a.lastName ?? '',
|
||||||
name: "${a.firstName} ${a.lastName}",
|
name: "${a.firstName} ${a.lastName}",
|
||||||
designation: a.jobRoleName,
|
designation: a.jobRoleName ?? '',
|
||||||
jobRole: a.jobRoleName,
|
jobRole: a.jobRoleName ?? '',
|
||||||
jobRoleID: a.jobRoleId,
|
jobRoleID: a.jobRoleId ?? '',
|
||||||
email: a.email ?? '',
|
email: a.email ?? '',
|
||||||
phoneNumber: '',
|
phoneNumber: '',
|
||||||
activity: 0,
|
activity: 0,
|
||||||
@ -495,7 +496,7 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
isAttendanceExpanded.value =
|
isAttendanceExpanded.value =
|
||||||
!isAttendanceExpanded.value;
|
!isAttendanceExpanded.value;
|
||||||
if (isAttendanceExpanded.value && job != null) {
|
if (isAttendanceExpanded.value ) {
|
||||||
await controller
|
await controller
|
||||||
.fetchJobAttendanceLog(job.attendanceId ?? '');
|
.fetchJobAttendanceLog(job.attendanceId ?? '');
|
||||||
}
|
}
|
||||||
@ -774,11 +775,11 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> with UIMixin {
|
|||||||
titleIcon: Icons.label_outline,
|
titleIcon: Icons.label_outline,
|
||||||
children: [_tagEditor()]),
|
children: [_tagEditor()]),
|
||||||
MySpacing.height(16),
|
MySpacing.height(16),
|
||||||
if (job.updateLogs.isNotEmpty)
|
if ((job.updateLogs?.isNotEmpty ?? false))
|
||||||
_buildSectionCard(
|
_buildSectionCard(
|
||||||
title: "Update Logs",
|
title: "Update Logs",
|
||||||
titleIcon: Icons.history,
|
titleIcon: Icons.history,
|
||||||
children: [JobTimeline(logs: job.updateLogs)]),
|
children: [JobTimeline(logs: job.updateLogs ?? [])]),
|
||||||
MySpacing.height(80),
|
MySpacing.height(80),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -806,12 +807,14 @@ class JobTimeline extends StatelessWidget {
|
|||||||
itemBuilder: (_, index) {
|
itemBuilder: (_, index) {
|
||||||
final log = reversedLogs[index];
|
final log = reversedLogs[index];
|
||||||
final statusName = log.status?.displayName ?? "Created";
|
final statusName = log.status?.displayName ?? "Created";
|
||||||
final nextStatusName = log.nextStatus.displayName;
|
final nextStatusName = log.nextStatus?.displayName ?? "N/A";
|
||||||
final comment = log.comment;
|
final comment = log.comment ?? '';
|
||||||
final updatedBy =
|
final updatedBy =
|
||||||
"${log.updatedBy.firstName} ${log.updatedBy.lastName}";
|
"${log.updatedBy?.firstName ?? ''} ${log.updatedBy?.lastName ?? ''}";
|
||||||
|
final f = log.updatedBy?.firstName ?? '';
|
||||||
|
final l = log.updatedBy?.lastName ?? '';
|
||||||
final initials =
|
final initials =
|
||||||
"${log.updatedBy.firstName.isNotEmpty ? log.updatedBy.firstName[0] : ''}${log.updatedBy.lastName.isNotEmpty ? log.updatedBy.lastName[0] : ''}";
|
"${f.isNotEmpty ? f[0] : ''}${l.isNotEmpty ? l[0] : ''}";
|
||||||
|
|
||||||
return TimelineTile(
|
return TimelineTile(
|
||||||
alignment: TimelineAlign.start,
|
alignment: TimelineAlign.start,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user