feat: show persisted investment data and sync state
Consume the provided resource-envelope API snapshot. Preserve financial snapshots during refresh, observe synchronization without importing, and fence late responses across account and connection changes.
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
||||
useStockQuote,
|
||||
} from "@/entities/stock";
|
||||
import { section } from "@/features/instrument-details";
|
||||
import { useScreenSync } from "@/features/tbank-connection";
|
||||
import { apiErrorCode } from "@/shared/api";
|
||||
import { formatDate, instrumentLogoUrl } from "@/shared/lib";
|
||||
|
||||
@@ -58,6 +59,17 @@ function useStockPageVm() {
|
||||
...firstPage,
|
||||
cursor: cursors.at(-1),
|
||||
});
|
||||
const sync = useScreenSync(
|
||||
{
|
||||
screen: "stock",
|
||||
instrumentUid: uid,
|
||||
candlePeriod: period,
|
||||
accountId: "all",
|
||||
categories: categories[filter],
|
||||
limit: 20,
|
||||
},
|
||||
[stock, quote, candles, position, company, dividends, operations],
|
||||
);
|
||||
const setParam = (key: string, value: string) => {
|
||||
const next = new URLSearchParams(params);
|
||||
next.set(key, value);
|
||||
@@ -70,7 +82,7 @@ function useStockPageVm() {
|
||||
queryKey: brokerageOperationsQueryOptions("all", firstPage).queryKey,
|
||||
exact: true,
|
||||
});
|
||||
} else void operations.refetch();
|
||||
} else void sync.refresh();
|
||||
};
|
||||
const chartData =
|
||||
candles.data?.candles.map((candle) => ({
|
||||
@@ -85,20 +97,23 @@ function useStockPageVm() {
|
||||
: null;
|
||||
const companyData = company.data;
|
||||
return {
|
||||
refresh: sync.refresh,
|
||||
refreshing: sync.refreshing,
|
||||
refreshError: sync.transportError || sync.sourceError,
|
||||
canonicalTo:
|
||||
stock.data?.slug && stock.data.slug !== stockId
|
||||
? `/stocks/${encodeURIComponent(stock.data.slug)}${params.size ? `?${params.toString()}` : ""}`
|
||||
: null,
|
||||
stock: stock.data,
|
||||
stockState: section(stock),
|
||||
stockState: section(stock, uid ? sync.refresh : () => stock.refetch()),
|
||||
code: apiErrorCode(stock.error),
|
||||
logoSrc: instrumentLogoUrl(stock.data?.logoName),
|
||||
quote: quote.data,
|
||||
quoteState: section(quote),
|
||||
quoteState: section(quote, sync.refresh),
|
||||
candles: candles.data,
|
||||
chartData,
|
||||
priceRows: chartData.toReversed(),
|
||||
candlesState: section(candles),
|
||||
candlesState: section(candles, sync.refresh),
|
||||
period,
|
||||
setPeriod: (value: string) => setParam("period", value),
|
||||
averageLine:
|
||||
@@ -106,11 +121,11 @@ function useStockPageVm() {
|
||||
hasIncompleteCandle:
|
||||
candles.data?.candles.some((candle) => !candle.isComplete) ?? false,
|
||||
position: position.data,
|
||||
positionState: section(position),
|
||||
positionState: section(position, sync.refresh),
|
||||
company: companyData,
|
||||
companyState: section(company),
|
||||
companyState: section(company, sync.refresh),
|
||||
dividends: dividends.data,
|
||||
dividendsState: section(dividends),
|
||||
dividendsState: section(dividends, sync.refresh),
|
||||
upcoming:
|
||||
dividends.data?.dividends
|
||||
.filter((event) => event.timing === "upcoming")
|
||||
@@ -128,7 +143,10 @@ function useStockPageVm() {
|
||||
),
|
||||
) ?? [],
|
||||
operations: operations.data,
|
||||
operationsState: { ...section(operations), retry: retryOperations },
|
||||
operationsState: {
|
||||
...section(operations, sync.refresh),
|
||||
retry: retryOperations,
|
||||
},
|
||||
eventRows:
|
||||
operations.data?.items.map((item) => ({
|
||||
...item,
|
||||
|
||||
Reference in New Issue
Block a user