refactor: enforce frontend view model boundaries
Frontend verify / commits (pull_request) Successful in 28s
Frontend verify / security (pull_request) Successful in 10s
Frontend verify / verify (pull_request) Successful in 8m19s

This commit is contained in:
2026-09-28 18:48:23 +03:00
parent 5b69003516
commit ca0ad4f824
287 changed files with 8558 additions and 4538 deletions
@@ -21,11 +21,13 @@ import { ProtectedDocumentTitle } from "./DocumentTitle";
const Navigation: FC = () => {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate("/accounts/all/income")} type="button">
Все счета
</button>
<button onClick={() => navigate(-1)} type="button">
Назад
</button>
@@ -39,6 +41,7 @@ const renderTitle = (path: string) =>
<MemoryRouter initialEntries={[path]}>
<AuthProvider>
<ProtectedDocumentTitle />
<Navigation />
</AuthProvider>
</MemoryRouter>
@@ -59,10 +62,13 @@ beforeEach(() => {
describe("document titles", () => {
it("updates a loading account name and follows account scope and history", async () => {
const { promise: accountsReady, resolve: resolveAccounts } = Promise.withResolvers<void>();
const { promise: accountsReady, resolve: resolveAccounts }
= Promise.withResolvers<void>();
server.use(
http.get("*/api/v1/brokerage-accounts", async () => {
await accountsReady;
return HttpResponse.json(resource([{ id: "a", name: "ИИС" }]));
}),
);
@@ -102,6 +108,7 @@ describe("document titles", () => {
server.use(
http.get("*/api/v1/stocks/by-ticker/:ticker", () => {
isRequested = true;
return HttpResponse.json({ code: "NOT_FOUND" }, { status: 404 });
}),
);
+18 -1
View File
@@ -24,29 +24,36 @@ type AccountDocumentTitleProps = {
const AccountDocumentTitle: FC<AccountDocumentTitleProps> = (props) => {
const { t } = useTranslation();
const { data } = useBrokerageAccounts();
const accountName
= props.accountId === "all"
? t("accounts.all")
: (data?.find(account => account.id === props.accountId)?.name
?? t("account.title"));
let section = t("portfolio.title");
switch (props.section ?? "") {
case "income": {
section = t("income.title");
break;
}
case "operations": {
section = t("ledger.title");
break;
}
case "events": {
section = t("events.title");
break;
}
default: {
break;
}
}
return <DocumentTitle title={`${section} — ${accountName}`} />;
};
@@ -55,18 +62,21 @@ type InstrumentDocumentTitleProps = { identifier: string };
const BondDocumentTitle: FC<InstrumentDocumentTitleProps> = (props) => {
const { t } = useTranslation();
const { data } = useBond(props.identifier);
return <DocumentTitle title={data?.name ?? t("bond.instrument")} />;
};
const StockDocumentTitle: FC<InstrumentDocumentTitleProps> = (props) => {
const { t } = useTranslation();
const { data } = useStock(props.identifier);
return <DocumentTitle title={data?.name ?? t("stock.share")} />;
};
const CardDocumentTitle: FC<InstrumentDocumentTitleProps> = (props) => {
const { t } = useTranslation();
const { data } = useBankCard(props.identifier);
return <DocumentTitle title={data?.name ?? t("bank.card")} />;
};
@@ -94,7 +104,14 @@ const ProtectedDocumentTitle: FC = () => {
if (cards) return <DocumentTitle title={t("navigation.cards")} />;
if (bonds) return <DocumentTitle title={t("navigation.bonds")} />;
if (stocks) return <DocumentTitle title={t("navigation.stocks")} />;
return settings ? <DocumentTitle title={t("navigation.settings")} /> : <DocumentTitle title={t("navigation.accounts")} />;
return settings
? (
<DocumentTitle title={t("navigation.settings")} />
)
: (
<DocumentTitle title={t("navigation.accounts")} />
);
};
export { ProtectedDocumentTitle };