feat: add Control Room with containers and stacks management
- Add Control Room page with stacks sidebar and containers list - Implement container actions (start/stop/restart) with snackbars - Add container logs viewer dialog - Add search/filter for both stacks and containers lists - Add external links for Portainer and Netdata (url_launcher) - Add VS Code launch configuration for Flutter web debugging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
dd6bcbdbda
commit
3b89ed8c18
@@ -0,0 +1,84 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../../domain/entities/container.dart';
|
||||
import '../../domain/repositories/container_repository.dart';
|
||||
import '../datasources/containers_datasource.dart';
|
||||
|
||||
part 'container_repository_impl.g.dart';
|
||||
|
||||
/// Implementation of ContainerRepository using remote datasource.
|
||||
class ContainerRepositoryImpl implements ContainerRepository {
|
||||
ContainerRepositoryImpl(this._datasource);
|
||||
|
||||
final ContainersDatasource _datasource;
|
||||
|
||||
@override
|
||||
Future<List<Container>> getContainers() async {
|
||||
final models = await _datasource.getContainers();
|
||||
return models.map((m) => m.toEntity()).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Container>> getContainersByStack(String stackId) async {
|
||||
final containers = await getContainers();
|
||||
return containers.where((c) => c.stackId == stackId).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Container> getContainer(String id) async {
|
||||
final model = await _datasource.getContainer(id);
|
||||
return model.toEntity();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> startContainer(String id) async {
|
||||
await _datasource.containerAction(id, 'start');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> stopContainer(String id) async {
|
||||
await _datasource.containerAction(id, 'stop');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> restartContainer(String id) async {
|
||||
await _datasource.containerAction(id, 'restart');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> pauseContainer(String id) async {
|
||||
await _datasource.containerAction(id, 'pause');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> unpauseContainer(String id) async {
|
||||
await _datasource.containerAction(id, 'unpause');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeContainer(String id, {bool force = false}) async {
|
||||
await _datasource.removeContainer(id, force: force);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getContainerLogs(
|
||||
String id, {
|
||||
int? tail,
|
||||
bool timestamps = false,
|
||||
}) async {
|
||||
return _datasource.getContainerLogs(id, tail: tail, timestamps: timestamps);
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<String> streamContainerLogs(String id, {bool timestamps = false}) {
|
||||
// TODO: Implement WebSocket/SSE streaming
|
||||
throw UnimplementedError('Log streaming not yet implemented');
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides the container repository.
|
||||
@riverpod
|
||||
ContainerRepository containerRepository(ContainerRepositoryRef ref) {
|
||||
final datasource = ref.watch(containersDatasourceProvider);
|
||||
return ContainerRepositoryImpl(datasource);
|
||||
}
|
||||
Reference in New Issue
Block a user