Files
frontend/src/pages/bond/ui/BondPage/BondPage.vm.ts
T
ksv741 5b30bb802a feat: add quiet reading with rare confirmations
Part of the quiet-user-feedback change; docs and specs land in their own repositories.
2026-10-06 07:01:58 +03:00

102 lines
2.6 KiB
TypeScript

import { useParams } from "react-router";
import {
useBond,
useBondCandles,
useBondCoupons,
useBondMetrics,
useBondPosition,
useBondQuote,
} from "@/entities/bond";
import { useBrokerageOperationHistory } from "@/entities/broker-operation";
import {
section,
toInstrumentEventRows,
useInstrumentParameters,
} from "@/features/instrument-details";
import { useScreenSync } from "@/features/tbank-connection";
import { apiErrorCode } from "@/shared/api";
import { compareDateDesc, instrumentLogoUrl } from "@/shared/lib";
type BondPageVm = ReturnType<typeof useBondPageVm>;
function useBondPageVm() {
const { bondId = "" } = useParams();
const bond = useBond(bondId);
const uid = bond.data?.instrumentUid ?? "";
const { categories, filter, period, search, setFilter, setPeriod }
= useInstrumentParameters("coupons");
const quote = useBondQuote(uid);
const metrics = useBondMetrics(uid);
const candles = useBondCandles(uid, period);
const position = useBondPosition(uid);
const coupons = useBondCoupons(uid);
const history = useBrokerageOperationHistory(uid ? "all" : undefined, {
categories,
instrumentUid: uid,
limit: 20,
});
const { operations } = history;
useScreenSync(
{
accountId: "all",
candlePeriod: period,
categories,
instrumentUid: uid,
limit: 20,
screen: "bond",
},
[bond, quote, candles, position, metrics, coupons, operations],
);
return {
bond: bond.data,
bondState: section(bond),
candles: candles.data,
candlesState: section(candles),
canonicalTo:
bond.data?.slug && bond.data.slug !== bondId
? `/bonds/${encodeURIComponent(bond.data.slug)}${search}`
: null,
code: apiErrorCode(bond.error),
coupons: coupons.data,
couponsState: section(coupons),
eventRows: toInstrumentEventRows(operations.data?.items, bond.data),
filter,
hasPrevious: history.hasPrevious,
logoSrc: instrumentLogoUrl(bond.data?.logoName),
metrics: metrics.data,
metricsState: section(metrics),
onNext: history.onNext,
onPrevious: history.onPrevious,
operations: operations.data,
operationsState: section(operations),
pastCoupons:
coupons.data?.coupons
.filter(event => event.timing !== "upcoming")
.toSorted((a, b) =>
compareDateDesc(a.paymentDate, b.paymentDate),
) ?? [],
period,
position: position.data,
positionState: section(position),
quote: quote.data,
quoteState: section(quote),
setFilter,
setPeriod,
upcoming:
coupons.data?.coupons
.filter(event => event.timing === "upcoming")
.toSorted((a, b) =>
compareDateDesc(b.paymentDate, a.paymentDate),
) ?? [],
};
}
export { type BondPageVm, useBondPageVm };