import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../../../core/models/models.dart'; import '../../../core/models/severity_mapping.dart'; import '../../../core/theme/theme_x.dart'; import '../../../core/widgets/data_table_scaffold.dart'; import '../../../core/widgets/empty_state.dart'; import '../../../core/widgets/mono_text.dart'; import '../../../core/widgets/status_pill.dart'; class UpdatesTable extends StatelessWidget { const UpdatesTable({super.key, required this.records, required this.onDelete}); final List records; final void Function(UpdateRecord record) onDelete; @override Widget build(BuildContext context) { final sorted = [...records]..sort((a, b) => b.timestamp.compareTo(a.timestamp)); final timeFormat = DateFormat('yyyy-MM-dd HH:mm'); return DataTableScaffold( empty: const EmptyState( icon: Icons.history_rounded, title: 'No update history yet', message: 'OS package update runs will show up here.', ), columns: const [ DataColumn(label: Text('Timestamp')), DataColumn(label: Text('Result')), DataColumn(label: Text('Packages')), DataColumn(label: Text('Message')), DataColumn(label: Text('')), ], rows: [ for (final record in sorted) DataRow( cells: [ DataCell(MonoText(timeFormat.format(record.timestamp.toLocal()))), DataCell( StatusPill( label: record.success ? 'success' : 'failed', severity: severityForSuccess(record.success), ), ), DataCell(_PackageChips(packages: record.packages)), DataCell( ConstrainedBox( constraints: const BoxConstraints(maxWidth: 320), child: Text(record.message, maxLines: 1, overflow: TextOverflow.ellipsis), ), ), DataCell( IconButton( tooltip: 'Delete', icon: const Icon(Icons.delete_outline, size: 18), onPressed: () => onDelete(record), ), ), ], ), ], ); } } class _PackageChips extends StatelessWidget { const _PackageChips({required this.packages}); final List packages; static const _maxShown = 2; @override Widget build(BuildContext context) { if (packages.isEmpty) { return Text('—', style: context.text.bodySmall); } final shown = packages.take(_maxShown).toList(); final remaining = packages.length - shown.length; return Wrap( spacing: 4, runSpacing: 4, children: [ for (final package in shown) Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: context.colors.surfaceContainerHighest, borderRadius: BorderRadius.circular(4), ), child: Text(package, style: context.dataStyles.dataMonoSmall), ), if (remaining > 0) Text('+$remaining more', style: context.text.bodySmall), ], ); } }