cyberhybridhub/lib/admin/utils/sync_run_formatters.dart
2026-05-31 11:17:12 -05:00

102 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
import '../../theme/app_theme.dart';
import '../models/sync_run_event.dart';
String formatRelativeTime(DateTime startedAt, {DateTime? now}) {
final DateTime reference = (now ?? DateTime.now()).toUtc();
final Duration delta = reference.difference(startedAt.toUtc());
if (delta.inMinutes < 1) {
return 'just now';
}
if (delta.inHours < 1) {
return '${delta.inMinutes}m ago';
}
if (delta.inDays < 1) {
return '${delta.inHours}h ago';
}
return '${delta.inDays}d ago';
}
String formatMarketHistorySlotWire(DateTime value) {
final DateTime utc = value.toUtc();
final int slotHour = (utc.hour ~/ 4) * 4;
final DateTime slotStart = DateTime.utc(
utc.year,
utc.month,
utc.day,
slotHour,
);
String two(int n) => n.toString().padLeft(2, '0');
return '${slotStart.year.toString().padLeft(4, '0')}-'
'${two(slotStart.month)}-${two(slotStart.day)}T'
'${two(slotStart.hour)}:${two(slotStart.minute)}:${two(slotStart.second)}Z';
}
String formatUtcTimestamp(DateTime? value) {
if (value == null) {
return '';
}
final DateTime utc = value.toUtc();
final String hour = utc.hour.toString().padLeft(2, '0');
final String minute = utc.minute.toString().padLeft(2, '0');
return '${utc.year}-${utc.month.toString().padLeft(2, '0')}-'
'${utc.day.toString().padLeft(2, '0')} $hour:$minute UTC';
}
String formatLocalTimestamp(DateTime? value) {
if (value == null) {
return '';
}
final DateTime local = value.toLocal();
final String hour = local.hour.toString().padLeft(2, '0');
final String minute = local.minute.toString().padLeft(2, '0');
return '${local.year}-${local.month.toString().padLeft(2, '0')}-'
'${local.day.toString().padLeft(2, '0')} $hour:$minute';
}
String formatDurationMs(int? durationMs) {
if (durationMs == null) {
return '';
}
if (durationMs < 1000) {
return '${durationMs}ms';
}
return '${(durationMs / 1000).toStringAsFixed(1)}s';
}
String shortStatusLabel(SyncRunEvent event) {
return switch (event.status) {
SyncRunStatus.success => 'Success',
SyncRunStatus.failed => 'Failed',
SyncRunStatus.partial => 'Partial success',
SyncRunStatus.inProgress => 'In progress',
};
}
IconData severityIcon(SyncRunSeverity severity) {
return switch (severity) {
SyncRunSeverity.ok => Icons.check_circle_outline,
SyncRunSeverity.warning => Icons.schedule,
SyncRunSeverity.error => Icons.error_outline,
SyncRunSeverity.rateLimit => Icons.speed,
};
}
Color severityColor(SyncRunSeverity severity) {
return switch (severity) {
SyncRunSeverity.ok => AppColors.success,
SyncRunSeverity.warning => Colors.orange,
SyncRunSeverity.error => const Color(0xFFF87171),
SyncRunSeverity.rateLimit => Colors.amber,
};
}
String? parseHttpStatus(String? error) {
if (error == null || error.trim().isEmpty) {
return null;
}
final RegExpMatch? match = RegExp(r'\b(\d{3})\b').firstMatch(error);
return match?.group(1);
}