Frontend verify / commits (pull_request) Successful in 29s
Frontend verify / security (pull_request) Successful in 8s
Frontend verify / verify (pull_request) Successful in 5m25s
Frontend verify / commits (push) Skipped
Frontend verify / security (push) Successful in 9s
Frontend verify / verify (push) Failing after 5m20s
218 lines
5.4 KiB
TypeScript
218 lines
5.4 KiB
TypeScript
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
|
|
import { MemoryRouter } from "react-router";
|
|
|
|
import { resource } from "@/test/resource";
|
|
|
|
import type { BrokerageAccount } from "../../api/useBrokerageAccounts";
|
|
|
|
import { brokerageAccountCards } from "../../model/display";
|
|
import { BrokerageAccountList } from "./BrokerageAccountList";
|
|
|
|
type PortfolioSummary = NonNullable<BrokerageAccount["portfolioSummary"]>;
|
|
|
|
const rubReturn = {
|
|
absolute: "136900",
|
|
costBasis: "1103600.50",
|
|
currency: "RUB",
|
|
partial: false,
|
|
percent: "12.40",
|
|
};
|
|
|
|
const portfolioSummary = {
|
|
bondPositionCount: 12,
|
|
cashBalances: [
|
|
{ currency: "RUB", value: "82500.50" },
|
|
{ currency: "USD", value: "1500" },
|
|
],
|
|
fundPositionCount: 2,
|
|
stockPositionCount: 5,
|
|
structure: {
|
|
currencies: [{
|
|
categories: [
|
|
{ sharePercent: "55.000000", type: "STOCK", value: "682500" },
|
|
{ sharePercent: "25.000000", type: "BOND", value: "310500" },
|
|
{ sharePercent: "10.000000", type: "OTHER", value: "124200" },
|
|
{ sharePercent: "10.000000", type: "CASH", value: "124200" },
|
|
],
|
|
currency: "RUB",
|
|
hasNegativeValues: false,
|
|
totalValue: "1241400",
|
|
}],
|
|
unvaluedCategories: [],
|
|
},
|
|
totalPositionCount: 19,
|
|
totalsByCurrency: [{ currency: "RUB", value: "1240500.50" }],
|
|
unrealizedReturnByCurrency: [rubReturn],
|
|
} satisfies PortfolioSummary;
|
|
|
|
function account(
|
|
id: string,
|
|
name: string,
|
|
summary: null | PortfolioSummary = portfolioSummary,
|
|
type: BrokerageAccount["type"] = "BROKERAGE",
|
|
): BrokerageAccount {
|
|
return {
|
|
id,
|
|
name,
|
|
openedOn: "2025-03-15",
|
|
portfolioSummary: summary,
|
|
type,
|
|
};
|
|
}
|
|
|
|
const negativeSummary: PortfolioSummary = {
|
|
...portfolioSummary,
|
|
unrealizedReturnByCurrency: [{
|
|
...rubReturn,
|
|
absolute: "-4200",
|
|
percent: "-3.05",
|
|
}],
|
|
};
|
|
|
|
const emptySummary: PortfolioSummary = {
|
|
...portfolioSummary,
|
|
cashBalances: [],
|
|
structure: { currencies: [], unvaluedCategories: [] },
|
|
totalPositionCount: 0,
|
|
totalsByCurrency: [],
|
|
unrealizedReturnByCurrency: [],
|
|
};
|
|
|
|
const meta = {
|
|
args: { accounts: brokerageAccountCards([account("normal", "Основной ИИС")]) },
|
|
argTypes: { accounts: { control: false } },
|
|
component: BrokerageAccountList,
|
|
decorators: [
|
|
Story => (
|
|
<MemoryRouter initialEntries={["/accounts"]}>
|
|
<Story />
|
|
</MemoryRouter>
|
|
),
|
|
],
|
|
parameters: {
|
|
docs: {
|
|
description: {
|
|
component:
|
|
"Карточки счетов: стоимость и доходность по валютам, деньги, структура и свежесть источника. Денежные и процентные значения остаются строками. Все примеры содержат вымышленные данные; ссылки работают только внутри MemoryRouter.",
|
|
},
|
|
},
|
|
},
|
|
tags: ["autodocs"],
|
|
title: "Product/BrokerageAccountList",
|
|
} satisfies Meta<typeof BrokerageAccountList>;
|
|
|
|
export default meta;
|
|
|
|
type Story = StoryObj<typeof meta>;
|
|
|
|
export const Normal: Story = {};
|
|
|
|
export const MultiCurrency: Story = {
|
|
args: {
|
|
accounts: brokerageAccountCards([account("multi", "Мультивалютный", {
|
|
...portfolioSummary,
|
|
cashBalances: [
|
|
{ currency: "RUB", value: "82500.50" },
|
|
{ currency: "USD", value: "1500" },
|
|
],
|
|
totalsByCurrency: [
|
|
{ currency: "RUB", value: "1240500.50" },
|
|
{ currency: "USD", value: "3200" },
|
|
{ currency: "EUR", value: "900" },
|
|
],
|
|
unrealizedReturnByCurrency: [
|
|
...portfolioSummary.unrealizedReturnByCurrency,
|
|
{
|
|
absolute: "20",
|
|
costBasis: "3180",
|
|
currency: "USD",
|
|
partial: false,
|
|
percent: "2.10",
|
|
},
|
|
{
|
|
absolute: "0",
|
|
costBasis: "900",
|
|
currency: "EUR",
|
|
partial: false,
|
|
percent: null,
|
|
},
|
|
],
|
|
})]),
|
|
},
|
|
};
|
|
|
|
export const Negative: Story = {
|
|
args: {
|
|
accounts: brokerageAccountCards([
|
|
account("negative", "Просевший портфель", negativeSummary),
|
|
]),
|
|
},
|
|
};
|
|
|
|
export const Partial: Story = {
|
|
args: {
|
|
accounts: brokerageAccountCards([account("partial", "Частичные данные", {
|
|
...portfolioSummary,
|
|
unrealizedReturnByCurrency: [{
|
|
...rubReturn,
|
|
partial: true,
|
|
}],
|
|
})]),
|
|
},
|
|
};
|
|
|
|
export const Empty: Story = {
|
|
args: {
|
|
accounts: brokerageAccountCards([
|
|
account("empty", "Новый пустой счёт", emptySummary),
|
|
]),
|
|
},
|
|
};
|
|
|
|
export const Unavailable: Story = {
|
|
args: {
|
|
accounts: brokerageAccountCards([
|
|
account("unavailable", "Счёт без сводки", null),
|
|
]),
|
|
},
|
|
};
|
|
|
|
export const Stale: Story = {
|
|
args: {
|
|
accounts: brokerageAccountCards([
|
|
account("stale", "Устаревший портфель"),
|
|
], resource([], {
|
|
dependencies: [{
|
|
availability: "available",
|
|
completeness: "complete",
|
|
dataRevision: "stale-revision",
|
|
freshness: "stale",
|
|
lastAttempt: {
|
|
finishedAt: null,
|
|
problems: [],
|
|
startedAt: null,
|
|
state: "none",
|
|
},
|
|
lastSuccessfulAt: "2026-08-13T00:00:00Z",
|
|
resourceKey: "portfolio/stale",
|
|
}],
|
|
freshness: "stale",
|
|
lastSuccessfulAt: "2026-08-14T00:00:00Z",
|
|
}).meta.dependencies),
|
|
},
|
|
};
|
|
|
|
export const LongName: Story = {
|
|
args: {
|
|
accounts: brokerageAccountCards([
|
|
account(
|
|
"long",
|
|
"Очень длинное название индивидуального инвестиционного счёта, которое должно корректно переноситься на узком экране",
|
|
portfolioSummary,
|
|
"INDIVIDUAL_INVESTMENT",
|
|
),
|
|
]),
|
|
},
|
|
};
|