Sergey Krylov af0aaeda9d feat(frontend): add dashboard visual helpers for HTML parity
Introduce dashboardVisual.ts with moneyTone, formatDashboardCurrency,
eventTypeTone, incomeTypeTone, and instrumentDisplay helpers used by
the broker dashboard to match the HTML reference prototype.

Extend dashboardIncome.ts: typeLabel now distinguishes DIV_EXT
('Дивиденд (внешний)'), and rows expose instrumentMain/instrumentSubtitle
via instrumentDisplay while keeping instrument as a derived alias for
existing callers.

Add resetDashboardFilters factory in dashboardFilters.ts so Task 3 can
wire the reset action without re-churning filter types.
2026-06-27 12:46:39 +03:00

59 lines
1.9 KiB
TypeScript

import type { BrokerMoney, BrokerOperation } from '@/shared/api'
import { instrumentDisplay } from './dashboardVisual'
const INCOME_TYPES = new Set([
'OPERATION_TYPE_DIVIDEND',
'OPERATION_TYPE_DIV_EXT',
'OPERATION_TYPE_COUPON',
])
export type DashboardIncomeTypeLabel = 'Дивиденд' | 'Дивиденд (внешний)' | 'Купон'
export type DashboardIncomeRow = {
id: string
date: string | null
instrumentMain: string
instrumentSubtitle: string | null
instrument: string
typeLabel: DashboardIncomeTypeLabel
amount: BrokerMoney
}
export function isDashboardIncomeOperation(operation: BrokerOperation): boolean {
return INCOME_TYPES.has(operation.type) && operation.payment !== null
}
function typeLabel(type: string): DashboardIncomeTypeLabel {
if (type === 'OPERATION_TYPE_COUPON') return 'Купон'
if (type === 'OPERATION_TYPE_DIV_EXT') return 'Дивиденд (внешний)'
return 'Дивиденд'
}
export function getDashboardIncomeRows(operations: BrokerOperation[]): DashboardIncomeRow[] {
return operations.filter(isDashboardIncomeOperation).map((operation) => {
const { main, subtitle } = instrumentDisplay({
ticker: operation.ticker,
name: operation.name,
description: operation.description,
})
return {
id: String(operation.id ?? operation.cursor ?? `${operation.type}-${operation.date}`),
date: typeof operation.date === 'string' ? operation.date : null,
instrumentMain: main,
instrumentSubtitle: subtitle,
instrument: main,
typeLabel: typeLabel(operation.type),
amount: operation.payment!,
}
})
}
export function sumDashboardIncome(
rows: DashboardIncomeRow[],
): { currency: string; value: number } | null {
if (rows.length === 0) return null
const currency = rows[0].amount.currency
const value = rows.reduce((sum, row) => sum + row.amount.value, 0)
return { currency, value }
}