Announcements and IT Job Checklist

This commit is contained in:
2026-03-21 18:51:04 +08:00
parent 7d9096963a
commit 3fb6fd5c93
19 changed files with 2367 additions and 37 deletions
+70
View File
@@ -0,0 +1,70 @@
import '../utils/app_time.dart';
class Announcement {
Announcement({
required this.id,
required this.authorId,
required this.title,
required this.body,
required this.visibleRoles,
required this.isTemplate,
this.templateId,
required this.createdAt,
required this.updatedAt,
});
final String id;
final String authorId;
final String title;
final String body;
final List<String> visibleRoles;
final bool isTemplate;
final String? templateId;
final DateTime createdAt;
final DateTime updatedAt;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Announcement &&
runtimeType == other.runtimeType &&
id == other.id &&
authorId == other.authorId &&
title == other.title &&
body == other.body &&
isTemplate == other.isTemplate &&
templateId == other.templateId &&
createdAt == other.createdAt &&
updatedAt == other.updatedAt;
@override
int get hashCode => Object.hash(
id,
authorId,
title,
body,
isTemplate,
templateId,
createdAt,
updatedAt,
);
factory Announcement.fromMap(Map<String, dynamic> map) {
final rolesRaw = map['visible_roles'];
final roles = rolesRaw is List
? rolesRaw.cast<String>()
: <String>[];
return Announcement(
id: map['id'] as String,
authorId: map['author_id'] as String,
title: map['title'] as String? ?? '',
body: map['body'] as String? ?? '',
visibleRoles: roles,
isTemplate: map['is_template'] as bool? ?? false,
templateId: map['template_id'] as String?,
createdAt: AppTime.parse(map['created_at'] as String),
updatedAt: AppTime.parse(map['updated_at'] as String),
);
}
}
+47
View File
@@ -0,0 +1,47 @@
import '../utils/app_time.dart';
class AnnouncementComment {
AnnouncementComment({
required this.id,
required this.announcementId,
required this.authorId,
required this.body,
required this.createdAt,
});
final String id;
final String announcementId;
final String authorId;
final String body;
final DateTime createdAt;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AnnouncementComment &&
runtimeType == other.runtimeType &&
id == other.id &&
announcementId == other.announcementId &&
authorId == other.authorId &&
body == other.body &&
createdAt == other.createdAt;
@override
int get hashCode => Object.hash(
id,
announcementId,
authorId,
body,
createdAt,
);
factory AnnouncementComment.fromMap(Map<String, dynamic> map) {
return AnnouncementComment(
id: map['id'] as String,
announcementId: map['announcement_id'] as String,
authorId: map['author_id'] as String,
body: map['body'] as String? ?? '',
createdAt: AppTime.parse(map['created_at'] as String),
);
}
}
+3
View File
@@ -10,6 +10,7 @@ class NotificationItem {
this.leaveId,
this.passSlipId,
required this.itServiceRequestId,
this.announcementId,
required this.messageId,
required this.type,
required this.createdAt,
@@ -24,6 +25,7 @@ class NotificationItem {
final String? leaveId;
final String? passSlipId;
final String? itServiceRequestId;
final String? announcementId;
final int? messageId;
final String type;
final DateTime createdAt;
@@ -41,6 +43,7 @@ class NotificationItem {
leaveId: map['leave_id'] as String?,
passSlipId: map['pass_slip_id'] as String?,
itServiceRequestId: map['it_service_request_id'] as String?,
announcementId: map['announcement_id'] as String?,
messageId: map['message_id'] as int?,
type: map['type'] as String? ?? 'mention',
createdAt: AppTime.parse(map['created_at'] as String),
+19 -2
View File
@@ -27,6 +27,9 @@ class Task {
this.actionTaken,
this.cancellationReason,
this.cancelledAt,
this.itJobPrinted = false,
this.itJobPrintedAt,
this.itJobReceivedById,
});
final String id;
@@ -59,6 +62,11 @@ class Task {
final String? cancellationReason;
final DateTime? cancelledAt;
/// Whether the printed IT Job has been submitted.
final bool itJobPrinted;
final DateTime? itJobPrintedAt;
final String? itJobReceivedById;
@override
bool operator ==(Object other) =>
identical(this, other) ||
@@ -85,7 +93,10 @@ class Task {
requestCategory == other.requestCategory &&
actionTaken == other.actionTaken &&
cancellationReason == other.cancellationReason &&
cancelledAt == other.cancelledAt;
cancelledAt == other.cancelledAt &&
itJobPrinted == other.itJobPrinted &&
itJobPrintedAt == other.itJobPrintedAt &&
itJobReceivedById == other.itJobReceivedById;
@override
int get hashCode => Object.hash(
@@ -109,7 +120,8 @@ class Task {
requestTypeOther,
requestCategory,
// Object.hash supports max 20 positional args; combine remainder.
Object.hash(actionTaken, cancellationReason, cancelledAt),
Object.hash(actionTaken, cancellationReason, cancelledAt,
itJobPrinted, itJobPrintedAt, itJobReceivedById),
);
/// Helper that indicates whether a completed task still has missing
@@ -154,6 +166,11 @@ class Task {
cancelledAt: map['cancelled_at'] == null
? null
: AppTime.parse(map['cancelled_at'] as String),
itJobPrinted: map['it_job_printed'] as bool? ?? false,
itJobPrintedAt: map['it_job_printed_at'] == null
? null
: AppTime.parse(map['it_job_printed_at'] as String),
itJobReceivedById: map['it_job_received_by_id'] as String?,
actionTaken: (() {
final at = map['action_taken'];
if (at == null) return null;