Files
tatlock-ui/lib/features/control_room/containers/data/models/container_model.dart
T
Jeroen SchweitzerandClaude Opus 4.5 6989241ae7 chore: upgrade to riverpod 3.x and freezed 3.x
- Upgrade flutter_riverpod to 3.1.0, riverpod_annotation to 4.0.0
- Upgrade freezed to 3.2.3, freezed_annotation to 3.1.0
- Migrate freezed classes to use sealed keyword (freezed 3.x)
- Update provider naming (*NotifierProvider → *Provider)
- Add legacy.dart import for StateNotifierProvider compatibility
- Fix valueOrNull → value for AsyncValue
- Remove unused imports and fields
- Add sync from Authentik button to users/groups pages
- Suppress invalid_annotation_target warning in analysis_options

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 00:07:01 +01:00

130 lines
4.0 KiB
Dart

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:tatlock_ui/features/control_room/containers/domain/entities/container.dart';
part 'container_model.freezed.dart';
part 'container_model.g.dart';
/// Container data model for API serialization.
@freezed
sealed class ContainerModel with _$ContainerModel {
const factory ContainerModel({
@JsonKey(name: 'Id') required String id,
@JsonKey(name: 'Names') required List<String> names,
@JsonKey(name: 'Image') required String image,
@JsonKey(name: 'State') required String state,
@JsonKey(name: 'Status') required String status,
@JsonKey(name: 'Labels') @Default({}) Map<String, String> labels,
@JsonKey(name: 'Ports') @Default([]) List<PortModel> ports,
@JsonKey(name: 'Mounts') @Default([]) List<MountModel> mounts,
@JsonKey(name: 'NetworkSettings') NetworkSettingsModel? networkSettings,
@JsonKey(name: 'Created') int? created,
@JsonKey(name: 'SizeRw') int? sizeRw,
@JsonKey(name: 'SizeRootFs') int? sizeRootFs,
}) = _ContainerModel;
const ContainerModel._();
factory ContainerModel.fromJson(Map<String, dynamic> json) =>
_$ContainerModelFromJson(json);
/// Converts to domain entity.
Container toEntity() {
// Extract stack name from labels (Docker Compose convention)
final stackName = labels['com.docker.compose.project'];
final stackId = stackName; // Use project name as ID for now
return Container(
id: id.substring(0, 12),
fullId: id,
name: names.isNotEmpty ? names.first.replaceFirst('/', '') : id,
image: image,
state: _parseState(state),
status: status,
stackName: stackName,
stackId: stackId,
ports: ports.map((p) => p.toEntity()).toList(),
labels: labels,
mounts: mounts.map((m) => m.toEntity()).toList(),
networks: networkSettings?.networks.keys.toList() ?? [],
createdAt: created != null
? DateTime.fromMillisecondsSinceEpoch(created! * 1000)
: null,
);
}
ContainerState _parseState(String state) {
return switch (state.toLowerCase()) {
'created' => ContainerState.created,
'running' => ContainerState.running,
'paused' => ContainerState.paused,
'restarting' => ContainerState.restarting,
'removing' => ContainerState.removing,
'exited' => ContainerState.exited,
'dead' => ContainerState.dead,
_ => ContainerState.exited,
};
}
}
/// Port mapping model.
@freezed
sealed class PortModel with _$PortModel {
const factory PortModel({
@JsonKey(name: 'IP') String? ip,
@JsonKey(name: 'PrivatePort') required int privatePort,
@JsonKey(name: 'PublicPort') int? publicPort,
@JsonKey(name: 'Type') @Default('tcp') String type,
}) = _PortModel;
const PortModel._();
factory PortModel.fromJson(Map<String, dynamic> json) =>
_$PortModelFromJson(json);
PortMapping toEntity() {
return PortMapping(
hostIp: ip,
hostPort: publicPort,
containerPort: privatePort,
protocol: type,
);
}
}
/// Mount model.
@freezed
sealed class MountModel with _$MountModel {
const factory MountModel({
@JsonKey(name: 'Type') required String type,
@JsonKey(name: 'Source') required String source,
@JsonKey(name: 'Destination') required String destination,
@JsonKey(name: 'Mode') @Default('rw') String mode,
@JsonKey(name: 'RW') @Default(true) bool rw,
}) = _MountModel;
const MountModel._();
factory MountModel.fromJson(Map<String, dynamic> json) =>
_$MountModelFromJson(json);
VolumeMount toEntity() {
return VolumeMount(
type: type,
source: source,
destination: destination,
mode: rw ? 'rw' : 'ro',
);
}
}
/// Network settings model.
@freezed
sealed class NetworkSettingsModel with _$NetworkSettingsModel {
const factory NetworkSettingsModel({
@JsonKey(name: 'Networks') @Default({}) Map<String, dynamic> networks,
}) = _NetworkSettingsModel;
factory NetworkSettingsModel.fromJson(Map<String, dynamic> json) =>
_$NetworkSettingsModelFromJson(json);
}