Offline Support

This commit is contained in:
2026-04-27 06:20:39 +08:00
parent 7d8851a94a
commit 48cd3bcd60
121 changed files with 14798 additions and 2214 deletions
+53 -11
View File
@@ -3,10 +3,12 @@ import '../theme/m3_motion.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/profile.dart';
import '../models/task_assignment.dart';
import '../providers/profile_provider.dart';
import '../providers/tasks_provider.dart';
import '../theme/app_surfaces.dart';
import '../utils/snackbar.dart';
import 'sync_pending_badge.dart';
class TaskAssignmentSection extends ConsumerWidget {
const TaskAssignmentSection({
@@ -30,7 +32,21 @@ class TaskAssignmentSection extends ConsumerWidget {
.where((task) => task.id == taskId)
.map((task) => task.ticketId)
.firstOrNull;
final assignments = assignmentsAsync.valueOrNull ?? [];
final liveAssignments = assignmentsAsync.valueOrNull ?? <TaskAssignment>[];
final pendingUserIds =
ref.watch(offlinePendingAssignmentsProvider)[taskId];
final assignments = pendingUserIds != null
? [
...liveAssignments.where((a) => a.taskId != taskId),
...pendingUserIds.map(
(uid) => TaskAssignment(
taskId: taskId,
userId: uid,
createdAt: DateTime.now(),
),
),
]
: liveAssignments;
final itStaff =
profiles.where((profile) => profile.role == 'it_staff').toList()
@@ -90,16 +106,42 @@ class TaskAssignmentSection extends ConsumerWidget {
final label = profile?.fullName.isNotEmpty == true
? profile!.fullName
: assignment.userId;
return InputChip(
label: Text(label),
onDeleted: canAssign
? () => ref
.read(taskAssignmentsControllerProvider)
.removeAssignment(
taskId: taskId,
userId: assignment.userId,
)
: null,
final isPendingAssignment =
pendingUserIds?.contains(assignment.userId) ?? false;
return Stack(
clipBehavior: Clip.none,
children: [
InputChip(
label: Text(label),
onDeleted: canAssign
? () async {
try {
await ref
.read(taskAssignmentsControllerProvider)
.removeAssignment(
taskId: taskId,
userId: assignment.userId,
);
} catch (e) {
if (context.mounted) {
showErrorSnackBar(
context,
'Failed to remove assignment',
);
}
}
}
: null,
),
Positioned(
top: -6,
right: -6,
child: SyncPendingBadge(
isPending: isPendingAssignment,
compact: true,
),
),
],
);
}).toList(),
),