Files
manager/lib/features/services/widgets/services_table.dart
T

89 lines
3.2 KiB
Dart
Raw Normal View History

2026-07-27 14:42:23 +02:00
import 'package:flutter/material.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 ServicesTable extends StatelessWidget {
const ServicesTable({
super.key,
required this.services,
required this.onRowTap,
required this.onToggleRunning,
required this.busyServiceIds,
});
final List<Service> services;
final void Function(Service service) onRowTap;
final void Function(Service service) onToggleRunning;
final Set<String> busyServiceIds;
String _backupSummary(Service service) {
final targets = service.backup?.targets ?? const [];
if (targets.isEmpty) return 'none';
if (targets.length == 1) return targets.first.method.name;
return '${targets.length} targets';
}
@override
Widget build(BuildContext context) {
return DataTableScaffold(
empty: const EmptyState(
icon: Icons.layers_outlined,
title: 'No services yet',
message: 'Scan a compose folder from the Dashboard, or add one manually.',
),
columns: const [
DataColumn(label: Text('Service')),
DataColumn(label: Text('Status')),
DataColumn(label: Text('Compose file')),
DataColumn(label: Text('Backup')),
DataColumn(label: Text('')),
],
rows: [
for (final service in services)
DataRow(
onSelectChanged: (_) => onRowTap(service),
cells: [
DataCell(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(service.name, style: context.text.labelLarge),
Text(
service.composeType?.isNotEmpty == true ? service.composeType! : 'docker compose',
style: context.text.bodySmall,
),
],
),
),
DataCell(
StatusPill(label: service.status, severity: severityForServiceStatus(service.status)),
),
DataCell(MonoText(service.composeFile)),
DataCell(
_backupSummary(service) == 'none'
? Text('none', style: context.text.bodySmall)
: Text(_backupSummary(service), style: context.text.bodyMedium),
),
DataCell(
busyServiceIds.contains(service.id)
? const SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2))
: IconButton(
tooltip: service.status == 'up' ? 'Stop' : 'Start',
icon: Icon(service.status == 'up' ? Icons.stop_rounded : Icons.play_arrow_rounded, size: 20),
onPressed: () => onToggleRunning(service),
),
),
],
),
],
);
}
}