style(app): остальные экраны под новый визуальный язык и форматирование
Доходы, ребалансировка, налоги, импорт, цели, здоровье данных, правила, транзакции, категории, cashflow, pending: новые виджеты и токены темы, dart format. Тесты подстроены под новые модели.
This commit is contained in:
@@ -50,7 +50,9 @@ class IncomeForecastTab extends ConsumerWidget {
|
||||
StatTile(
|
||||
label: 'Доходность к стоимости',
|
||||
// null means "нет оценки стоимости" and must not read as 0 %
|
||||
value: Text(formatPercent(data.annualYieldOnValue, signed: false)),
|
||||
value: Text(
|
||||
formatPercent(data.annualYieldOnValue, signed: false),
|
||||
),
|
||||
note: data.annualYieldOnValue == null
|
||||
? 'нет оценки текущей стоимости'
|
||||
: 'ожидаемый доход / стоимость портфеля',
|
||||
@@ -58,7 +60,10 @@ class IncomeForecastTab extends ConsumerWidget {
|
||||
for (final b in bases)
|
||||
StatTile(
|
||||
label: 'Основание: ${basisLabel(b)}',
|
||||
value: MoneyText(_basisTotal(data, b).toString(), currency: 'RUB'),
|
||||
value: MoneyText(
|
||||
_basisTotal(data, b).toString(),
|
||||
currency: 'RUB',
|
||||
),
|
||||
note: basisDescription(b),
|
||||
width: 220,
|
||||
),
|
||||
@@ -91,8 +96,14 @@ class IncomeForecastTab extends ConsumerWidget {
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SizedBox(
|
||||
width: (data.months.length * 52).toDouble().clamp(320, double.infinity),
|
||||
child: _ForecastChart(months: data.months, bases: bases),
|
||||
width: (data.months.length * 52).toDouble().clamp(
|
||||
320,
|
||||
double.infinity,
|
||||
),
|
||||
child: _ForecastChart(
|
||||
months: data.months,
|
||||
bases: bases,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -130,7 +141,8 @@ class _HorizonChips extends ConsumerWidget {
|
||||
ChoiceChip(
|
||||
label: Text('$m мес'),
|
||||
selected: months == m,
|
||||
onSelected: (_) => ref.read(forecastMonthsProvider.notifier).state = m,
|
||||
onSelected: (_) =>
|
||||
ref.read(forecastMonthsProvider.notifier).state = m,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -191,10 +203,16 @@ class _BasisLegend extends StatelessWidget {
|
||||
Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: BoxDecoration(color: basisColor(b), shape: BoxShape.circle),
|
||||
decoration: BoxDecoration(
|
||||
color: basisColor(b),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(basisLabel(b), style: Theme.of(context).textTheme.bodySmall),
|
||||
Text(
|
||||
basisLabel(b),
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -235,7 +253,8 @@ class _ForecastChart extends StatelessWidget {
|
||||
getTitlesWidget: (value, meta) {
|
||||
final i = value.round();
|
||||
if (i < 0 || i >= months.length) return const SizedBox.shrink();
|
||||
if (months.length > 14 && i.isOdd) return const SizedBox.shrink();
|
||||
if (months.length > 14 && i.isOdd)
|
||||
return const SizedBox.shrink();
|
||||
final m = months[i].month;
|
||||
return Text(
|
||||
m == null ? '—' : ruMonthYearShort(m),
|
||||
@@ -251,7 +270,8 @@ class _ForecastChart extends StatelessWidget {
|
||||
final m = months[group.x];
|
||||
final parts = [
|
||||
for (final b in bases)
|
||||
if ((Decimal.tryParse(m.byBasis[b] ?? '0') ?? Decimal.zero) > Decimal.zero)
|
||||
if ((Decimal.tryParse(m.byBasis[b] ?? '0') ?? Decimal.zero) >
|
||||
Decimal.zero)
|
||||
'${basisLabel(b)}: ${MoneyText.format(m.byBasis[b]!, 'RUB')}',
|
||||
];
|
||||
return BarTooltipItem(
|
||||
@@ -277,7 +297,8 @@ class _ForecastChart extends StatelessWidget {
|
||||
final stack = <BarChartRodStackItem>[];
|
||||
var from = 0.0;
|
||||
for (final b in bases) {
|
||||
final v = (Decimal.tryParse(m.byBasis[b] ?? '0') ?? Decimal.zero).toDouble();
|
||||
final v = (Decimal.tryParse(m.byBasis[b] ?? '0') ?? Decimal.zero)
|
||||
.toDouble();
|
||||
if (v <= 0) continue;
|
||||
stack.add(BarChartRodStackItem(from, from + v, basisColor(b)));
|
||||
from += v;
|
||||
@@ -321,14 +342,18 @@ class _ForecastTable extends StatelessWidget {
|
||||
for (final m in months)
|
||||
DataRow(
|
||||
cells: [
|
||||
DataCell(Text(m.month == null ? '—' : ruMonthYearShort(m.month!))),
|
||||
DataCell(
|
||||
Text(m.month == null ? '—' : ruMonthYearShort(m.month!)),
|
||||
),
|
||||
for (final b in bases)
|
||||
DataCell(MoneyText(m.byBasis[b] ?? '0', currency: 'RUB')),
|
||||
DataCell(MoneyText(
|
||||
m.amountRub,
|
||||
currency: 'RUB',
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
)),
|
||||
DataCell(
|
||||
MoneyText(
|
||||
m.amountRub,
|
||||
currency: 'RUB',
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user