Proper signatories
This commit is contained in:
parent
d778654837
commit
74f9511ee3
|
|
@ -13,11 +13,8 @@ import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter_quill/flutter_quill.dart' as quill;
|
import 'package:flutter_quill/flutter_quill.dart' as quill;
|
||||||
import 'dart:typed_data';
|
import '../../providers/services_provider.dart';
|
||||||
import 'package:flutter/services.dart' show rootBundle;
|
import 'task_pdf.dart';
|
||||||
import 'package:pdf/widgets.dart' as pw;
|
|
||||||
import 'package:pdf/pdf.dart' as pdf;
|
|
||||||
import 'package:printing/printing.dart';
|
|
||||||
import '../../providers/supabase_provider.dart';
|
import '../../providers/supabase_provider.dart';
|
||||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||||
import '../../providers/profile_provider.dart';
|
import '../../providers/profile_provider.dart';
|
||||||
|
|
@ -361,7 +358,37 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||||
tooltip: 'Preview/print task',
|
tooltip: 'Preview/print task',
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
try {
|
try {
|
||||||
await _showPdfPreview(task, ticket, officeName);
|
final logsAsync = ref.read(
|
||||||
|
taskActivityLogsProvider(task.id),
|
||||||
|
);
|
||||||
|
final logs =
|
||||||
|
logsAsync.valueOrNull ?? <TaskActivityLog>[];
|
||||||
|
final assignmentList = assignments;
|
||||||
|
final profilesList =
|
||||||
|
profilesAsync.valueOrNull ?? <Profile>[];
|
||||||
|
final servicesAsync = ref.read(servicesProvider);
|
||||||
|
final servicesById = {
|
||||||
|
for (final s in servicesAsync.valueOrNull ?? [])
|
||||||
|
s.id: s,
|
||||||
|
};
|
||||||
|
final serviceName = officeId == null
|
||||||
|
? ''
|
||||||
|
: (officeById[officeId]?.serviceId == null
|
||||||
|
? ''
|
||||||
|
: (servicesById[officeById[officeId]!
|
||||||
|
.serviceId]
|
||||||
|
?.name ??
|
||||||
|
''));
|
||||||
|
await showTaskPdfPreview(
|
||||||
|
context,
|
||||||
|
task,
|
||||||
|
ticket,
|
||||||
|
officeName,
|
||||||
|
serviceName,
|
||||||
|
logs,
|
||||||
|
assignmentList,
|
||||||
|
profilesList,
|
||||||
|
);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.print),
|
icon: const Icon(Icons.print),
|
||||||
|
|
@ -2755,185 +2782,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uint8List> _buildTaskPdfBytes(
|
// PDF preview/building moved to `task_pdf.dart`.
|
||||||
Task task,
|
|
||||||
Ticket? ticket,
|
|
||||||
String officeName,
|
|
||||||
pdf.PdfPageFormat format,
|
|
||||||
) async {
|
|
||||||
final logoData = await rootBundle.load('crmc_logo.png');
|
|
||||||
final logoImage = pw.MemoryImage(logoData.buffer.asUint8List());
|
|
||||||
final doc = pw.Document();
|
|
||||||
final created = AppTime.formatDate(task.createdAt);
|
|
||||||
|
|
||||||
doc.addPage(
|
|
||||||
pw.Page(
|
|
||||||
pageFormat: format,
|
|
||||||
margin: pw.EdgeInsets.all(28),
|
|
||||||
build: (pw.Context ctx) {
|
|
||||||
return pw.Column(
|
|
||||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
pw.Row(
|
|
||||||
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
pw.Container(
|
|
||||||
width: 64,
|
|
||||||
height: 64,
|
|
||||||
child: pw.Image(logoImage),
|
|
||||||
),
|
|
||||||
pw.SizedBox(width: 12),
|
|
||||||
pw.Expanded(
|
|
||||||
child: pw.Column(
|
|
||||||
crossAxisAlignment: pw.CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
pw.Text(
|
|
||||||
'Republic of the Philippines',
|
|
||||||
textAlign: pw.TextAlign.center,
|
|
||||||
),
|
|
||||||
pw.Text(
|
|
||||||
'Department of Health',
|
|
||||||
textAlign: pw.TextAlign.center,
|
|
||||||
),
|
|
||||||
pw.Text(
|
|
||||||
'Regional and Medical Center',
|
|
||||||
textAlign: pw.TextAlign.center,
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 6),
|
|
||||||
pw.Text(
|
|
||||||
'Cotabato Regional and Medical Center',
|
|
||||||
textAlign: pw.TextAlign.center,
|
|
||||||
style: pw.TextStyle(fontWeight: pw.FontWeight.bold),
|
|
||||||
),
|
|
||||||
pw.Text(
|
|
||||||
'Integrated Hospital Operations and Management Program',
|
|
||||||
textAlign: pw.TextAlign.center,
|
|
||||||
),
|
|
||||||
pw.Text('(IHOMP)', textAlign: pw.TextAlign.center),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 12),
|
|
||||||
pw.Center(
|
|
||||||
child: pw.Text(
|
|
||||||
'IT Job / Maintenance Request Form',
|
|
||||||
style: pw.TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: pw.FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 12),
|
|
||||||
pw.Row(
|
|
||||||
children: [
|
|
||||||
pw.Text('Task Number: ${task.taskNumber ?? task.id}'),
|
|
||||||
pw.Spacer(),
|
|
||||||
pw.Text('Filed At: $created'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 8),
|
|
||||||
pw.Row(
|
|
||||||
children: [
|
|
||||||
pw.Text('Service: ${task.title}'),
|
|
||||||
pw.SizedBox(width: 12),
|
|
||||||
pw.Text('Office: $officeName'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 8),
|
|
||||||
pw.Row(
|
|
||||||
children: [
|
|
||||||
pw.Text('Type: ${task.requestType ?? ''}'),
|
|
||||||
pw.SizedBox(width: 12),
|
|
||||||
pw.Text('Category: ${task.requestCategory ?? ''}'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 12),
|
|
||||||
pw.Text('Description:'),
|
|
||||||
pw.SizedBox(height: 6),
|
|
||||||
pw.Container(
|
|
||||||
height: 80,
|
|
||||||
decoration: pw.BoxDecoration(
|
|
||||||
border: pw.Border(
|
|
||||||
bottom: pw.BorderSide(
|
|
||||||
width: 0.5,
|
|
||||||
color: pdf.PdfColors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 12),
|
|
||||||
pw.Row(
|
|
||||||
children: [
|
|
||||||
pw.Text('Requested By: ${task.requestedBy ?? ''}'),
|
|
||||||
pw.Spacer(),
|
|
||||||
pw.Text('Noted by Supervisor/Senior'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 12),
|
|
||||||
pw.Text('Action Taken:'),
|
|
||||||
pw.SizedBox(height: 6),
|
|
||||||
pw.Container(
|
|
||||||
height: 80,
|
|
||||||
decoration: pw.BoxDecoration(
|
|
||||||
border: pw.Border(
|
|
||||||
bottom: pw.BorderSide(
|
|
||||||
width: 0.5,
|
|
||||||
color: pdf.PdfColors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 12),
|
|
||||||
pw.Row(
|
|
||||||
children: [
|
|
||||||
pw.Text('Performed By:'),
|
|
||||||
pw.Spacer(),
|
|
||||||
pw.Text('Received By: ___________________________'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return doc.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _showPdfPreview(
|
|
||||||
Task task,
|
|
||||||
Ticket? ticket,
|
|
||||||
String officeName,
|
|
||||||
) async {
|
|
||||||
await showDialog<void>(
|
|
||||||
context: context,
|
|
||||||
builder: (ctx) => AlertDialog(
|
|
||||||
contentPadding: const EdgeInsets.all(8),
|
|
||||||
content: SizedBox(
|
|
||||||
width: 700,
|
|
||||||
height: 900,
|
|
||||||
child: PdfPreview(
|
|
||||||
build: (format) => _buildTaskPdfBytes(
|
|
||||||
task,
|
|
||||||
ticket,
|
|
||||||
officeName,
|
|
||||||
format as pdf.PdfPageFormat,
|
|
||||||
),
|
|
||||||
allowPrinting: true,
|
|
||||||
allowSharing: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.of(ctx).pop(),
|
|
||||||
child: const Text('Close'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MetaBadge extends StatelessWidget {
|
class _MetaBadge extends StatelessWidget {
|
||||||
|
|
|
||||||
316
lib/screens/tasks/task_pdf.dart
Normal file
316
lib/screens/tasks/task_pdf.dart
Normal file
|
|
@ -0,0 +1,316 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart' show rootBundle;
|
||||||
|
import 'package:flutter_quill/flutter_quill.dart' as quill;
|
||||||
|
import 'package:pdf/widgets.dart' as pw;
|
||||||
|
import 'package:pdf/pdf.dart' as pdf;
|
||||||
|
import 'package:printing/printing.dart';
|
||||||
|
|
||||||
|
import '../../models/task.dart';
|
||||||
|
import '../../models/ticket.dart';
|
||||||
|
import '../../models/task_activity_log.dart';
|
||||||
|
import '../../models/task_assignment.dart';
|
||||||
|
import '../../models/profile.dart';
|
||||||
|
import '../../utils/app_time.dart';
|
||||||
|
|
||||||
|
Future<Uint8List> buildTaskPdfBytes(
|
||||||
|
Task task,
|
||||||
|
Ticket? ticket,
|
||||||
|
String officeName,
|
||||||
|
String serviceName,
|
||||||
|
List<TaskActivityLog> logs,
|
||||||
|
List<TaskAssignment> assignments,
|
||||||
|
List<Profile> profiles,
|
||||||
|
pdf.PdfPageFormat format,
|
||||||
|
) async {
|
||||||
|
final logoData = await rootBundle.load('crmc_logo.png');
|
||||||
|
final logoImage = pw.MemoryImage(logoData.buffer.asUint8List());
|
||||||
|
final doc = pw.Document();
|
||||||
|
final created = AppTime.formatDate(task.createdAt);
|
||||||
|
|
||||||
|
final descriptionText = ticket?.description ?? task.description;
|
||||||
|
|
||||||
|
String plainFromAction(String? at) {
|
||||||
|
if (at == null || at.trim().isEmpty) return '';
|
||||||
|
dynamic decoded = at;
|
||||||
|
for (var i = 0; i < 3; i++) {
|
||||||
|
if (decoded is String) {
|
||||||
|
try {
|
||||||
|
decoded = jsonDecode(decoded);
|
||||||
|
continue;
|
||||||
|
} catch (_) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoded is Map && decoded['ops'] is List) {
|
||||||
|
final ops = decoded['ops'] as List;
|
||||||
|
final buf = StringBuffer();
|
||||||
|
for (final op in ops) {
|
||||||
|
if (op is Map) {
|
||||||
|
final insert = op['insert'];
|
||||||
|
if (insert is String) {
|
||||||
|
buf.write(insert);
|
||||||
|
} else if (insert is Map && insert.containsKey('image')) {
|
||||||
|
buf.write('[image]');
|
||||||
|
} else {
|
||||||
|
buf.write(insert?.toString() ?? '');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf.write(op.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoded is List) {
|
||||||
|
try {
|
||||||
|
final doc = quill.Document.fromJson(decoded);
|
||||||
|
return doc.toPlainText().trim();
|
||||||
|
} catch (_) {
|
||||||
|
return decoded.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decoded.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
final actionTakenText = plainFromAction(task.actionTaken);
|
||||||
|
final requestedBy = task.requestedBy ?? '';
|
||||||
|
final notedBy = task.notedBy ?? '';
|
||||||
|
final receivedBy = task.receivedBy ?? '';
|
||||||
|
final profileById = {for (final p in profiles) p.id: p};
|
||||||
|
final assignedForTask = assignments.where((a) => a.taskId == task.id).toList()
|
||||||
|
..sort((a, b) => a.createdAt.compareTo(b.createdAt));
|
||||||
|
final latestAssignment = assignedForTask.isEmpty
|
||||||
|
? null
|
||||||
|
: assignedForTask.last;
|
||||||
|
final performedBy = latestAssignment == null
|
||||||
|
? ''
|
||||||
|
: (profileById[latestAssignment.userId]?.fullName ??
|
||||||
|
latestAssignment.userId);
|
||||||
|
|
||||||
|
doc.addPage(
|
||||||
|
pw.Page(
|
||||||
|
pageFormat: format,
|
||||||
|
margin: pw.EdgeInsets.all(28),
|
||||||
|
build: (pw.Context ctx) {
|
||||||
|
return pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
pw.Row(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
pw.Container(width: 64, height: 64, child: pw.Image(logoImage)),
|
||||||
|
pw.SizedBox(width: 12),
|
||||||
|
pw.Expanded(
|
||||||
|
child: pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
pw.Text(
|
||||||
|
'Republic of the Philippines',
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
pw.Text(
|
||||||
|
'Department of Health',
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
pw.Text(
|
||||||
|
'Regional and Medical Center',
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Text(
|
||||||
|
'Cotabato Regional and Medical Center',
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
style: pw.TextStyle(fontWeight: pw.FontWeight.bold),
|
||||||
|
),
|
||||||
|
pw.Text(
|
||||||
|
'Integrated Hospital Operations and Management Program',
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
pw.Text('(IHOMP)', textAlign: pw.TextAlign.center),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 12),
|
||||||
|
pw.Center(
|
||||||
|
child: pw.Text(
|
||||||
|
'IT Job / Maintenance Request Form',
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 12),
|
||||||
|
pw.Row(
|
||||||
|
children: [
|
||||||
|
pw.Text('Task Number: ${task.taskNumber ?? task.id}'),
|
||||||
|
pw.Spacer(),
|
||||||
|
pw.Text('Filed At: $created'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 8),
|
||||||
|
pw.Row(
|
||||||
|
children: [
|
||||||
|
pw.Text('Service: $serviceName'),
|
||||||
|
pw.SizedBox(width: 12),
|
||||||
|
pw.Text('Office: $officeName'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 8),
|
||||||
|
pw.Row(
|
||||||
|
children: [
|
||||||
|
pw.Text('Type: ${task.requestType ?? ''}'),
|
||||||
|
pw.SizedBox(width: 12),
|
||||||
|
pw.Text('Category: ${task.requestCategory ?? ''}'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 12),
|
||||||
|
pw.Text('Task Title: ${task.title}'),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Text('Description:'),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Container(
|
||||||
|
padding: pw.EdgeInsets.all(6),
|
||||||
|
child: pw.Text(descriptionText),
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 12),
|
||||||
|
// Requested/Noted signature lines
|
||||||
|
pw.Row(
|
||||||
|
children: [
|
||||||
|
pw.Expanded(
|
||||||
|
child: pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Container(height: 28),
|
||||||
|
pw.Container(height: 1, color: pdf.PdfColors.black),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Text(requestedBy),
|
||||||
|
pw.Text('Requested By'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(width: 12),
|
||||||
|
pw.Expanded(
|
||||||
|
child: pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Container(height: 28),
|
||||||
|
pw.Container(height: 1, color: pdf.PdfColors.black),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Text(notedBy),
|
||||||
|
pw.Text('Noted by Supervisor/Senior'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 12),
|
||||||
|
pw.Text('Action Taken:'),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Container(
|
||||||
|
padding: pw.EdgeInsets.all(6),
|
||||||
|
child: pw.Text(actionTakenText),
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 12),
|
||||||
|
pw.Text('History updates:'),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
for (final log in logs)
|
||||||
|
pw.Row(
|
||||||
|
children: [
|
||||||
|
pw.Text(AppTime.formatDate(log.createdAt)),
|
||||||
|
pw.SizedBox(width: 8),
|
||||||
|
pw.Text(AppTime.formatTime(log.createdAt)),
|
||||||
|
pw.SizedBox(width: 8),
|
||||||
|
pw.Text(log.actionType),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 12),
|
||||||
|
// Performed/Received signature lines
|
||||||
|
pw.Row(
|
||||||
|
children: [
|
||||||
|
pw.Expanded(
|
||||||
|
child: pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Container(height: 28),
|
||||||
|
pw.Container(height: 1, color: pdf.PdfColors.black),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Text(performedBy),
|
||||||
|
pw.Text('Performed By'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(width: 12),
|
||||||
|
pw.Expanded(
|
||||||
|
child: pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Container(height: 28),
|
||||||
|
pw.Container(height: 1, color: pdf.PdfColors.black),
|
||||||
|
pw.SizedBox(height: 6),
|
||||||
|
pw.Text(receivedBy),
|
||||||
|
pw.Text('Received By'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return doc.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> showTaskPdfPreview(
|
||||||
|
BuildContext context,
|
||||||
|
Task task,
|
||||||
|
Ticket? ticket,
|
||||||
|
String officeName,
|
||||||
|
String serviceName,
|
||||||
|
List<TaskActivityLog> logs,
|
||||||
|
List<TaskAssignment> assignments,
|
||||||
|
List<Profile> profiles,
|
||||||
|
) async {
|
||||||
|
await showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
contentPadding: const EdgeInsets.all(8),
|
||||||
|
content: SizedBox(
|
||||||
|
width: 700,
|
||||||
|
height: 900,
|
||||||
|
child: PdfPreview(
|
||||||
|
build: (format) => buildTaskPdfBytes(
|
||||||
|
task,
|
||||||
|
ticket,
|
||||||
|
officeName,
|
||||||
|
serviceName,
|
||||||
|
logs,
|
||||||
|
assignments,
|
||||||
|
profiles,
|
||||||
|
format,
|
||||||
|
),
|
||||||
|
allowPrinting: true,
|
||||||
|
allowSharing: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(ctx).pop(),
|
||||||
|
child: const Text('Close'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user