refactor: tighten types and reuse instrument UI
Frontend verify / commits (pull_request) Successful in 24s
Frontend verify / security (pull_request) Failing after 9s
Frontend verify / verify (pull_request) Skipped

This commit is contained in:
2026-09-29 06:15:31 +03:00
parent b404c1802a
commit 7c28a423dd
67 changed files with 380 additions and 347 deletions
@@ -1,6 +1,6 @@
import type { Portfolio } from "@/entities/portfolio";
const portfolio: Portfolio
const portfolio
= {
cashBalances: [{ currency: "USD", value: "1" }],
isStale: true,
@@ -42,10 +42,10 @@ const portfolio: Portfolio
ticker: null,
type: "FUND",
},
],
] satisfies [Portfolio["positions"][number], ...Portfolio["positions"]],
structure: { currencies: [], unvaluedCategories: [] },
totalsByCurrency: [{ currency: "RUB", value: "150" }],
};
} satisfies Portfolio;
const position: Portfolio["positions"][number] = {
...portfolio.positions[0],
+11 -11
View File
@@ -59,13 +59,13 @@ describe("account position sections", () => {
"bonds",
"other",
]);
expect(sections[2].groups.map(group => group.positions[0].figi)).toEqual([
expect(sections[2]?.groups.map(group => group.positions[0].figi)).toEqual([
"FIGI-FUND",
...otherTypes.map(type => `FIGI-${type}-NEXT`),
]);
expect(sections[0].groups[0].positions[0].shareText).toBe("40 %");
expect(sections[1].groups[0].positions[0].shareText).toBe("20 %");
expect(sections[2].groups[1].positions[0].shareText).toBe("20 %");
expect(sections[0]?.groups[0]?.positions[0].shareText).toBe("40 %");
expect(sections[1]?.groups[0]?.positions[0].shareText).toBe("20 %");
expect(sections[2]?.groups[1]?.positions[0].shareText).toBe("20 %");
expect(snapshot).toEqual(original);
});
@@ -125,10 +125,10 @@ describe("account position sections", () => {
figi: null,
},
{ ...second, figi: null },
])[0].groups,
])[0]?.groups,
).toHaveLength(1);
expect(
sections([position, { ...second, figi: "OTHER-FIGI" }])[0].groups,
sections([position, { ...second, figi: "OTHER-FIGI" }])[0]?.groups,
).toHaveLength(2);
expect(
@@ -143,19 +143,19 @@ describe("account position sections", () => {
figi: null,
isin: null,
},
])[0].groups,
])[0]?.groups,
).toHaveLength(2);
});
it("preserves one-account cards and does not merge repeated rows on the same account", () => {
expect(
sections([position, { ...second, account: position.account }])[0].groups,
sections([position, { ...second, account: position.account }])[0]?.groups,
).toHaveLength(2);
expect(
sections([
{ ...position, account: undefined },
{ ...second, account: undefined },
])[0].groups,
])[0]?.groups,
).toHaveLength(2);
});
@@ -170,9 +170,9 @@ describe("account position sections", () => {
];
const before = structuredClone(source);
const [group] = sections(source)[0].groups;
const group = sections(source)[0]?.groups[0];
expect(
group.positions.map(item => [
group?.positions.map(item => [
item.quantity,
item.currentValue,
item.averagePurchasePrice,
+1 -1
View File
@@ -11,7 +11,7 @@ type AccountPagePosition = Portfolio["positions"][number] & {
type AccountPagePositionGroup = {
key: string;
positions: AccountPagePosition[];
positions: [AccountPagePosition, ...AccountPagePosition[]];
};
type AccountPagePositionSection = {