style(app): остальные экраны под новый визуальный язык и форматирование

Доходы, ребалансировка, налоги, импорт, цели, здоровье данных, правила, транзакции, категории, cashflow, pending: новые виджеты и токены темы, dart format. Тесты подстроены под новые модели.
This commit is contained in:
Dmitry
2026-09-19 22:14:27 +03:00
parent 62d36aa3e8
commit 322c60a359
55 changed files with 2158 additions and 1080 deletions
+33 -20
View File
@@ -60,7 +60,8 @@ class PendingInstrument {
return isin ?? sourceKey;
}
static PendingInstrument fromJson(Map<String, dynamic> json) => PendingInstrument(
static PendingInstrument fromJson(Map<String, dynamic> json) =>
PendingInstrument(
id: asInt(json['id'])!,
source: asString(json['source']) ?? '',
sourceKey: asString(json['source_key']) ?? '',
@@ -98,7 +99,8 @@ class PendingResolveResult {
final bool aliasCreated;
final bool metricsRefreshed;
static PendingResolveResult fromJson(Map<String, dynamic> json) => PendingResolveResult(
static PendingResolveResult fromJson(Map<String, dynamic> json) =>
PendingResolveResult(
id: asInt(json['id']) ?? 0,
status: asString(json['status']) ?? 'resolved',
instrumentId: asInt(json['instrument_id']),
@@ -131,14 +133,14 @@ class NewInstrument {
final int? lot;
Map<String, dynamic> toJson() => {
'asset_class': assetClass,
'name': name,
'currency': currency,
if (isin != null && isin!.isNotEmpty) 'isin': isin,
if (ticker != null && ticker!.isNotEmpty) 'ticker': ticker,
if (board != null && board!.isNotEmpty) 'board': board,
if (lot != null) 'lot': lot,
};
'asset_class': assetClass,
'name': name,
'currency': currency,
if (isin != null && isin!.isNotEmpty) 'isin': isin,
if (ticker != null && ticker!.isNotEmpty) 'ticker': ticker,
if (board != null && board!.isNotEmpty) 'board': board,
if (lot != null) 'lot': lot,
};
}
/// The asset classes the contract allows, as wire strings.
@@ -172,7 +174,10 @@ class PendingApi {
queryParameters: {'status': status, 'limit': limit, 'offset': offset},
);
return (r.data ?? const [])
.map((e) => PendingInstrument.fromJson(Map<String, dynamic>.from(e as Map)))
.map(
(e) =>
PendingInstrument.fromJson(Map<String, dynamic>.from(e as Map)),
)
.toList();
}
@@ -182,10 +187,17 @@ class PendingApi {
Future<PendingResolveResult> create(int id, NewInstrument instrument) =>
_resolve(id, {'action': 'create', 'instrument': instrument.toJson()});
Future<PendingResolveResult> ignore(int id) => _resolve(id, {'action': 'ignore'});
Future<PendingResolveResult> ignore(int id) =>
_resolve(id, {'action': 'ignore'});
Future<PendingResolveResult> _resolve(int id, Map<String, dynamic> body) async {
final r = await _dio.post<Map<String, dynamic>>('$_base/$id/resolve', data: body);
Future<PendingResolveResult> _resolve(
int id,
Map<String, dynamic> body,
) async {
final r = await _dio.post<Map<String, dynamic>>(
'$_base/$id/resolve',
data: body,
);
return PendingResolveResult.fromJson(r.data ?? const {});
}
}
@@ -196,14 +208,15 @@ class PendingApi {
// not convert to `double` anywhere — a numeric JSON value (should one ever appear) is kept
// as its lossless string form and parsed into `Decimal` at the point of display.
String? asString(Object? v) => v == null ? null : (v is String ? v : v.toString());
String? asString(Object? v) =>
v == null ? null : (v is String ? v : v.toString());
int? asInt(Object? v) => switch (v) {
null => null,
final int i => i,
final String s => int.tryParse(s),
_ => null,
};
null => null,
final int i => i,
final String s => int.tryParse(s),
_ => null,
};
DateTime? asDate(Object? v) {
final s = asString(v);