Added programmer role and fixed snackbar not showing
This commit is contained in:
@@ -32,6 +32,7 @@ class _UserManagementScreenState extends ConsumerState<UserManagementScreen> {
|
||||
'standard',
|
||||
'dispatcher',
|
||||
'it_staff',
|
||||
'programmer',
|
||||
'admin',
|
||||
];
|
||||
|
||||
|
||||
@@ -132,9 +132,10 @@ class _AttendanceScreenState extends ConsumerState<AttendanceScreen>
|
||||
ColorScheme colors,
|
||||
Profile profile,
|
||||
) {
|
||||
final isAdmin = profile.role == 'admin';
|
||||
final isAdmin = profile.role == 'admin' || profile.role == 'programmer';
|
||||
final canFileLeave =
|
||||
profile.role == 'admin' ||
|
||||
profile.role == 'programmer' ||
|
||||
profile.role == 'dispatcher' ||
|
||||
profile.role == 'it_staff';
|
||||
|
||||
@@ -209,7 +210,7 @@ class _AttendanceScreenState extends ConsumerState<AttendanceScreen>
|
||||
}
|
||||
|
||||
void _showPassSlipDialog(BuildContext context, Profile profile) {
|
||||
final isAdmin = profile.role == 'admin';
|
||||
final isAdmin = profile.role == 'admin' || profile.role == 'programmer';
|
||||
if (isAdmin) {
|
||||
showWarningSnackBar(context, 'Admins cannot file pass slips.');
|
||||
return;
|
||||
|
||||
@@ -177,6 +177,7 @@ final dashboardMetricsProvider = Provider<AsyncValue<DashboardMetrics>>((ref) {
|
||||
.where(
|
||||
(profile) =>
|
||||
profile.role == 'admin' ||
|
||||
profile.role == 'programmer' ||
|
||||
profile.role == 'dispatcher' ||
|
||||
profile.role == 'it_staff',
|
||||
)
|
||||
|
||||
@@ -241,9 +241,15 @@ class _ItServiceRequestDetailScreenState
|
||||
if (profile == null) return false;
|
||||
final request = ref.read(itServiceRequestByIdProvider(widget.requestId));
|
||||
if (request == null) return false;
|
||||
// Admin, dispatcher can always edit; IT Staff and creator can edit in certain statuses
|
||||
if (profile.role == 'admin' || profile.role == 'dispatcher') return true;
|
||||
if (profile.role == 'it_staff') return true;
|
||||
// Admin, programmer, dispatcher can always edit; IT Staff and creator can edit in certain statuses
|
||||
if (profile.role == 'admin' ||
|
||||
profile.role == 'programmer' ||
|
||||
profile.role == 'dispatcher') {
|
||||
return true;
|
||||
}
|
||||
if (profile.role == 'it_staff') {
|
||||
return true;
|
||||
}
|
||||
if (request.creatorId == profile.id &&
|
||||
(request.status == 'draft' || request.status == 'pending_approval')) {
|
||||
return true;
|
||||
@@ -259,7 +265,11 @@ class _ItServiceRequestDetailScreenState
|
||||
bool get _canChangeStatus {
|
||||
final profile = ref.read(currentProfileProvider).valueOrNull;
|
||||
if (profile == null) return false;
|
||||
if (profile.role == 'admin' || profile.role == 'dispatcher') return true;
|
||||
if (profile.role == 'admin' ||
|
||||
profile.role == 'programmer' ||
|
||||
profile.role == 'dispatcher') {
|
||||
return true;
|
||||
}
|
||||
// Assigned IT staff can change status
|
||||
final assignments =
|
||||
ref.read(itServiceRequestAssignmentsProvider).valueOrNull ?? [];
|
||||
|
||||
@@ -140,6 +140,7 @@ class _ItServiceRequestsListScreenState
|
||||
final isPrivileged =
|
||||
currentProfile != null &&
|
||||
(currentProfile.role == 'admin' ||
|
||||
currentProfile.role == 'programmer' ||
|
||||
currentProfile.role == 'dispatcher' ||
|
||||
currentProfile.role == 'it_staff');
|
||||
|
||||
|
||||
@@ -663,8 +663,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
),
|
||||
);
|
||||
if (mounted) {
|
||||
showSuccessSnackBar(
|
||||
context,
|
||||
showSuccessSnackBarGlobal(
|
||||
'Task resumed',
|
||||
);
|
||||
}
|
||||
@@ -682,16 +681,14 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
),
|
||||
);
|
||||
if (mounted) {
|
||||
showInfoSnackBar(
|
||||
context,
|
||||
showInfoSnackBarGlobal(
|
||||
'Task paused',
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
showErrorSnackBar(
|
||||
context,
|
||||
showErrorSnackBarGlobal(
|
||||
e.toString(),
|
||||
);
|
||||
}
|
||||
@@ -4310,8 +4307,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
// Validate IT staff assignment before starting or completing
|
||||
if ((value == 'in_progress' || value == 'completed') &&
|
||||
!hasAssignedItStaff) {
|
||||
showWarningSnackBar(
|
||||
context,
|
||||
showWarningSnackBarGlobal(
|
||||
'Please assign at least one IT Staff member before ${value == 'in_progress' ? 'starting' : 'completing'} this task.',
|
||||
);
|
||||
return;
|
||||
@@ -4327,7 +4323,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
} catch (e) {
|
||||
// surface validation or other errors to user
|
||||
if (mounted) {
|
||||
showErrorSnackBar(context, e.toString());
|
||||
showErrorSnackBarGlobal(e.toString());
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4362,6 +4358,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
}
|
||||
final isGlobal =
|
||||
profile.role == 'admin' ||
|
||||
profile.role == 'programmer' ||
|
||||
profile.role == 'dispatcher' ||
|
||||
profile.role == 'it_staff';
|
||||
if (isGlobal) {
|
||||
@@ -4390,7 +4387,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
|
||||
if (bytes == null) {
|
||||
if (mounted) {
|
||||
showErrorSnackBar(context, 'Failed to read file');
|
||||
showErrorSnackBarGlobal('Failed to read file');
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -4399,7 +4396,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
const maxSizeBytes = 25 * 1024 * 1024;
|
||||
if (bytes.length > maxSizeBytes) {
|
||||
if (mounted) {
|
||||
showErrorSnackBar(context, 'File size exceeds 25MB limit');
|
||||
showErrorSnackBarGlobal('File size exceeds 25MB limit');
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -4457,12 +4454,12 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
|
||||
if (uploadSuccess) {
|
||||
debugPrint('Showing success message and reloading attachments');
|
||||
showSuccessSnackBar(context, 'File uploaded successfully');
|
||||
showSuccessSnackBarGlobal('File uploaded successfully');
|
||||
// Reload attachments list (non-blocking)
|
||||
_loadAttachments(taskId);
|
||||
debugPrint('Attachment reload triggered');
|
||||
} else {
|
||||
showErrorSnackBar(context, 'Upload failed: $errorMessage');
|
||||
showErrorSnackBarGlobal('Upload failed: $errorMessage');
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
@@ -4536,15 +4533,15 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
|
||||
if (mounted) {
|
||||
if (savePath != null && savePath.isNotEmpty) {
|
||||
showSuccessSnackBar(context, 'File saved to: $savePath');
|
||||
showSuccessSnackBarGlobal('File saved to: $savePath');
|
||||
} else {
|
||||
showInfoSnackBar(context, 'Download cancelled');
|
||||
showInfoSnackBarGlobal('Download cancelled');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Download error: $e');
|
||||
if (mounted) {
|
||||
showErrorSnackBar(context, 'Download error: $e');
|
||||
showErrorSnackBarGlobal('Download error: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4576,7 +4573,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||
]);
|
||||
|
||||
if (mounted) {
|
||||
showSuccessSnackBar(context, 'Attachment deleted');
|
||||
showSuccessSnackBarGlobal('Attachment deleted');
|
||||
// Reload attachments list
|
||||
await _loadAttachments(taskId);
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen>
|
||||
data: (profile) =>
|
||||
profile != null &&
|
||||
(profile.role == 'admin' ||
|
||||
profile.role == 'programmer' ||
|
||||
profile.role == 'dispatcher' ||
|
||||
profile.role == 'it_staff'),
|
||||
orElse: () => false,
|
||||
@@ -862,8 +863,7 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen>
|
||||
);
|
||||
if (context.mounted) {
|
||||
Navigator.of(dialogContext).pop();
|
||||
showSuccessSnackBar(
|
||||
context,
|
||||
showSuccessSnackBarGlobal(
|
||||
'Task "$title" has been created successfully.',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@ class _TicketDetailScreenState extends ConsumerState<TicketDetailScreen> {
|
||||
final canEdit =
|
||||
profile != null &&
|
||||
(profile.role == 'admin' ||
|
||||
profile.role == 'programmer' ||
|
||||
profile.role == 'dispatcher' ||
|
||||
profile.role == 'it_staff' ||
|
||||
profile.id == ticket.creatorId);
|
||||
|
||||
@@ -26,7 +26,8 @@ class WorkforceScreen extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final profileAsync = ref.watch(currentProfileProvider);
|
||||
final role = profileAsync.valueOrNull?.role ?? 'standard';
|
||||
final isAdmin = role == 'admin' || role == 'dispatcher';
|
||||
final isAdmin =
|
||||
role == 'admin' || role == 'programmer' || role == 'dispatcher';
|
||||
|
||||
return ResponsiveBody(
|
||||
child: LayoutBuilder(
|
||||
@@ -1486,6 +1487,7 @@ class _ScheduleGeneratorPanelState
|
||||
(profile) =>
|
||||
profile.role == 'it_staff' ||
|
||||
profile.role == 'admin' ||
|
||||
profile.role == 'programmer' ||
|
||||
profile.role == 'dispatcher',
|
||||
)
|
||||
.toList();
|
||||
|
||||
Reference in New Issue
Block a user