refactor: enforce frontend view model boundaries
This commit is contained in:
@@ -21,55 +21,78 @@ import { formatDate, instrumentLogoUrl } from "@/shared/lib";
|
||||
|
||||
const periods: BondPeriod[] = ["month", "halfYear", "year", "all"];
|
||||
const filters = ["all", "trades", "coupons", "other"] as const;
|
||||
|
||||
type BondEventFilter = (typeof filters)[number];
|
||||
|
||||
const categories: Record<BondEventFilter, OperationCategory[]> = {
|
||||
all: [],
|
||||
coupons: ["income"],
|
||||
other: ["tax", "fee", "transfer", "other"],
|
||||
trades: ["trade"],
|
||||
};
|
||||
|
||||
type BondPageVm = ReturnType<typeof useBondPageVm>;
|
||||
|
||||
function useBondPageVm() {
|
||||
const { bondId = "" } = useParams();
|
||||
const bond = useBond(bondId);
|
||||
const uid = bond.data?.instrumentUid ?? "";
|
||||
const [parameters, setParameters] = useSearchParams();
|
||||
|
||||
const period
|
||||
= periods.find(value => value === parameters.get("period")) ?? "month";
|
||||
|
||||
const filter
|
||||
= filters.find(value => value === parameters.get("events")) ?? "all";
|
||||
|
||||
const quote = useBondQuote(uid);
|
||||
const metrics = useBondMetrics(uid);
|
||||
const candles = useBondCandles(uid, period);
|
||||
const position = useBondPosition(uid);
|
||||
const coupons = useBondCoupons(uid);
|
||||
const history = useInstrumentOperations(uid, filter, /* eslint-disable-line security/detect-object-injection -- This lookup uses a fixed typed key set, not an arbitrary external property name. */ categories[filter]);
|
||||
|
||||
const history = useInstrumentOperations(
|
||||
uid,
|
||||
filter,
|
||||
// eslint-disable-next-line security/detect-object-injection -- This lookup uses a fixed typed key set, not an arbitrary external property name.
|
||||
categories[filter],
|
||||
);
|
||||
|
||||
const { operations } = history;
|
||||
|
||||
const sync = useScreenSync(
|
||||
{
|
||||
accountId: "all",
|
||||
candlePeriod: period,
|
||||
categories: /* eslint-disable-line security/detect-object-injection -- This lookup uses a fixed typed key set, not an arbitrary external property name. */ categories[filter],
|
||||
categories:
|
||||
// eslint-disable-next-line security/detect-object-injection -- This lookup uses a fixed typed key set, not an arbitrary external property name.
|
||||
categories[filter],
|
||||
instrumentUid: uid,
|
||||
limit: 20,
|
||||
screen: "bond",
|
||||
},
|
||||
[bond, quote, candles, position, metrics, coupons, operations],
|
||||
);
|
||||
|
||||
const setParameter = (key: string, value: string) => {
|
||||
const next = new URLSearchParams(parameters);
|
||||
next.set(key, value);
|
||||
setParameters(next, { replace: true });
|
||||
};
|
||||
|
||||
const chartData
|
||||
= candles.data?.candles.map(candle => ({
|
||||
...candle,
|
||||
date: formatDate(candle.time),
|
||||
price: Number(candle.close),
|
||||
})) ?? [];
|
||||
|
||||
const search = parameters.size > 0 ? `?${parameters.toString()}` : "";
|
||||
|
||||
return {
|
||||
averageLine: /* eslint-disable-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model. */ null,
|
||||
averageLine:
|
||||
// eslint-disable-next-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model.
|
||||
null,
|
||||
bond: bond.data,
|
||||
bondState: section(bond, uid ? sync.retry : () => bond.refetch()),
|
||||
candles: candles.data,
|
||||
@@ -77,7 +100,7 @@ function useBondPageVm() {
|
||||
canonicalTo:
|
||||
bond.data?.slug && bond.data.slug !== bondId
|
||||
? `/bonds/${encodeURIComponent(bond.data.slug)}${search}`
|
||||
: /* eslint-disable-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model. */ null,
|
||||
: null, // eslint-disable-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model.
|
||||
chartData,
|
||||
code: apiErrorCode(bond.error),
|
||||
coupons: coupons.data,
|
||||
@@ -85,8 +108,16 @@ function useBondPageVm() {
|
||||
eventRows:
|
||||
operations.data?.items.map(item => ({
|
||||
...item,
|
||||
logoName: item.logoName ?? bond.data?.logoName ?? /* eslint-disable-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model. */ null,
|
||||
ticker: item.ticker ?? bond.data?.ticker ?? /* eslint-disable-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model. */ null,
|
||||
logoName:
|
||||
item.logoName
|
||||
?? bond.data?.logoName
|
||||
// eslint-disable-next-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model.
|
||||
?? null,
|
||||
ticker:
|
||||
item.ticker
|
||||
?? bond.data?.ticker
|
||||
// eslint-disable-next-line unicorn/no-null -- Preserve the nullable domain value consumed by this view model.
|
||||
?? null,
|
||||
})) ?? [],
|
||||
filter,
|
||||
hasIncompleteCandle:
|
||||
|
||||
Reference in New Issue
Block a user