feat(app): новый визуальный язык, верхняя навигация, портфели, создание счетов и ручные события
Тема и общие виджеты (AssetIcon, ServiceMark, HelpTip, глоссарий), верхняя панель TopNav и вкладки Аналитики вместо NavSidebar, иконки PWA. Экраны: портфели, создание брокерского счёта, ручное событие, правка инструмента, Обзор карточками по скоупам и таблица активов, пересчёт метрик с опросом /metrics/status. design-system.md обновлён.
This commit is contained in:
@@ -42,14 +42,14 @@ class BenchmarkResult {
|
||||
bool get isPriceIndex => kind == 'price';
|
||||
|
||||
static BenchmarkResult fromJson(Map<String, dynamic> json) => BenchmarkResult(
|
||||
benchmarkId: asInt(json['benchmark_id']) ?? 0,
|
||||
code: asString(json['code']) ?? '—',
|
||||
kind: asString(json['kind']) ?? 'total_return',
|
||||
twr: asString(json['twr']),
|
||||
twrAnnualized: asString(json['twr_annualized']),
|
||||
daysSkipped: asInt(json['days_skipped']) ?? 0,
|
||||
excess: asString(json['excess']),
|
||||
);
|
||||
benchmarkId: asInt(json['benchmark_id']) ?? 0,
|
||||
code: asString(json['code']) ?? '—',
|
||||
kind: asString(json['kind']) ?? 'total_return',
|
||||
twr: asString(json['twr']),
|
||||
twrAnnualized: asString(json['twr_annualized']),
|
||||
daysSkipped: asInt(json['days_skipped']) ?? 0,
|
||||
excess: asString(json['excess']),
|
||||
);
|
||||
}
|
||||
|
||||
class BenchmarkRow {
|
||||
@@ -74,18 +74,22 @@ class BenchmarkRow {
|
||||
final int portfolioDaysSkipped;
|
||||
final List<BenchmarkResult> benchmarks;
|
||||
|
||||
bool get hasSkippedDays =>
|
||||
portfolioDaysSkipped > 0 || benchmarks.any((b) => b.daysSkipped > 0);
|
||||
bool get hasSkippedDays => portfolioDaysSkipped > 0 || benchmarksSkipDays;
|
||||
|
||||
/// Only the index side: the portfolio's own gaps are already marked next to its number.
|
||||
bool get benchmarksSkipDays => benchmarks.any((b) => b.daysSkipped > 0);
|
||||
|
||||
static BenchmarkRow fromJson(Map<String, dynamic> json) => BenchmarkRow(
|
||||
period: asString(json['period']) ?? 'all',
|
||||
dateFrom: asDate(json['date_from']),
|
||||
dateTo: asDate(json['date_to']),
|
||||
portfolioTwr: asString(json['portfolio_twr']),
|
||||
portfolioTwrAnnualized: asString(json['portfolio_twr_annualized']),
|
||||
portfolioDaysSkipped: asInt(json['portfolio_days_skipped']) ?? 0,
|
||||
benchmarks: asObjects(json['benchmarks']).map(BenchmarkResult.fromJson).toList(),
|
||||
);
|
||||
period: asString(json['period']) ?? 'all',
|
||||
dateFrom: asDate(json['date_from']),
|
||||
dateTo: asDate(json['date_to']),
|
||||
portfolioTwr: asString(json['portfolio_twr']),
|
||||
portfolioTwrAnnualized: asString(json['portfolio_twr_annualized']),
|
||||
portfolioDaysSkipped: asInt(json['portfolio_days_skipped']) ?? 0,
|
||||
benchmarks: asObjects(json['benchmarks'])
|
||||
.map(BenchmarkResult.fromJson)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
class BenchmarksApi {
|
||||
@@ -104,7 +108,9 @@ class BenchmarksApi {
|
||||
// `period` is repeatable; Dio serialises a list as repeated query parameters.
|
||||
queryParameters: {'scope': scope, 'period': periods},
|
||||
);
|
||||
final rows = asObjects((r.data ?? const {})['rows']).map(BenchmarkRow.fromJson).toList();
|
||||
final rows = asObjects((r.data ?? const {})['rows'])
|
||||
.map(BenchmarkRow.fromJson)
|
||||
.toList();
|
||||
return Cached(rows, fetchedAt: r.extra['fetchedAt'] as DateTime?);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user