feat(app): новый визуальный язык, верхняя навигация, портфели, создание счетов и ручные события
Тема и общие виджеты (AssetIcon, ServiceMark, HelpTip, глоссарий), верхняя панель TopNav и вкладки Аналитики вместо NavSidebar, иконки PWA. Экраны: портфели, создание брокерского счёта, ручное событие, правка инструмента, Обзор карточками по скоупам и таблица активов, пересчёт метрик с опросом /metrics/status. design-system.md обновлён.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:fintracker_api/fintracker_api.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../core/api/api_client.dart';
|
||||
import '../../core/auth/auth_controller.dart';
|
||||
import '../portfolio/providers.dart' show scopesProvider;
|
||||
import '../portfolios/providers.dart' show portfolioListProvider;
|
||||
import '../rebalance/providers.dart' show portfoliosProvider;
|
||||
import 'providers.dart';
|
||||
|
||||
/// Changes to accounts: one place for a single switch and for a bulk edit.
|
||||
abstract class AccountActions {
|
||||
/// Applies [patch] to every account in [ids]. Returns null on success, or a message naming
|
||||
/// how many failed and why. One failure does not stop the rest: a bulk «отключить» that
|
||||
/// stalls on the 20th of 30 accounts would leave the list half changed and silent.
|
||||
Future<String?> patch(Iterable<int> ids, AccountPatch patch);
|
||||
}
|
||||
|
||||
final accountActionsProvider = Provider<AccountActions>(
|
||||
(ref) => _ApiAccountActions(ref),
|
||||
);
|
||||
|
||||
class _ApiAccountActions implements AccountActions {
|
||||
_ApiAccountActions(this._ref);
|
||||
|
||||
final Ref _ref;
|
||||
|
||||
@override
|
||||
Future<String?> patch(Iterable<int> ids, AccountPatch patch) async {
|
||||
final list = ids.toList();
|
||||
final api = _ref.read(apiProvider).getAccountsApi();
|
||||
var failed = 0;
|
||||
String? reason;
|
||||
for (final id in list) {
|
||||
try {
|
||||
await api.accountsPatch(accountId: id, accountPatch: patch);
|
||||
} on DioException catch (e) {
|
||||
failed++;
|
||||
reason ??= problemMessage(e);
|
||||
}
|
||||
}
|
||||
_ref.invalidate(accountsProvider);
|
||||
if (patch.disabled != null ||
|
||||
patch.includeInNetWorth != null ||
|
||||
patch.role != null) {
|
||||
// net worth, scopes and portfolios all follow these switches: refetch what is derived
|
||||
// from them and rebuild the metrics once, however many accounts changed
|
||||
_ref
|
||||
..invalidate(scopesProvider)
|
||||
..invalidate(portfolioListProvider)
|
||||
..invalidate(portfoliosProvider);
|
||||
try {
|
||||
await _ref.read(apiProvider).getMetricsApi().metricsRefresh();
|
||||
} on DioException {
|
||||
// the next scheduled or manual refresh picks the change up
|
||||
}
|
||||
}
|
||||
return failed == 0
|
||||
? null
|
||||
: 'Не удалось изменить $failed из ${list.length}: $reason';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user