initial commit
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
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),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user