/sync и блок data quality на дашборде сведены в один /health с двумя вкладками (Источники, Качество данных); дашборд ссылается на неё вместо собственного bottom sheet. Список находок вынесен в общий виджет DataQualityList, чтобы не дублировать рендер.
74 lines
2.3 KiB
Dart
74 lines
2.3 KiB
Dart
import 'package:fintracker_api/fintracker_api.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import '../../core/widgets/empty_state.dart';
|
|
|
|
/// Maps a `/metrics/data-quality` row's severity string to a color. Shared by
|
|
/// the Здоровье page's findings list and the dashboard's summary chip so the
|
|
/// two surfaces never disagree on what a severity looks like.
|
|
Color severityColor(String severity) {
|
|
final s = severity.toLowerCase();
|
|
if (s.contains('crit') || s.contains('err')) return const Color(0xFFD03B3B);
|
|
if (s.contains('warn')) return const Color(0xFFFAB219);
|
|
if (s.contains('info') || s.contains('low')) return const Color(0xFF0CA30C);
|
|
return const Color(0xFFEC835A);
|
|
}
|
|
|
|
/// Renders `DataQualityRow`s as a colored-dot list: one implementation used
|
|
/// by both the Здоровье page and (if reused) the dashboard's quick peek.
|
|
class DataQualityList extends StatelessWidget {
|
|
const DataQualityList({required this.rows, super.key});
|
|
|
|
final List<DataQualityRow> rows;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (rows.isEmpty) {
|
|
return const EmptyState(
|
|
icon: Icons.check_circle_outline,
|
|
message: 'Проблем не найдено.',
|
|
);
|
|
}
|
|
return Column(
|
|
children: [for (final row in rows) _DataQualityTile(row: row)],
|
|
);
|
|
}
|
|
}
|
|
|
|
class _DataQualityTile extends StatelessWidget {
|
|
const _DataQualityTile({required this.row});
|
|
|
|
final DataQualityRow row;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Card(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(12),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
margin: const EdgeInsets.only(top: 4, right: 10),
|
|
width: 10,
|
|
height: 10,
|
|
decoration: BoxDecoration(color: severityColor(row.severity), shape: BoxShape.circle),
|
|
),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('${row.checkName} (${row.count})',
|
|
style: Theme.of(context).textTheme.titleSmall),
|
|
const SizedBox(height: 2),
|
|
Text(row.detail),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|