feat: add Storybook for WealthLedger components
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { MemoryRouter } from "react-router";
|
||||
import type { BrokerageEvent } from "@/entities/brokerage-event";
|
||||
import { RecentEvents } from "./RecentEvents.view";
|
||||
|
||||
const syntheticEvent = {
|
||||
type: "coupon",
|
||||
date: "2026-10-15",
|
||||
dateKind: "event",
|
||||
figi: null,
|
||||
instrumentUid: null,
|
||||
ticker: "DEMO",
|
||||
displayName: "Учебные облигации",
|
||||
projectedAmount: { currency: "RUB", value: "850.50" },
|
||||
} satisfies BrokerageEvent;
|
||||
|
||||
const eventsPath = "/accounts/storybook-account/events";
|
||||
|
||||
const meta = {
|
||||
title: "WealthLedger/RecentEvents",
|
||||
component: RecentEvents,
|
||||
tags: ["autodocs"],
|
||||
argTypes: {
|
||||
events: { control: false },
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<MemoryRouter initialEntries={["/accounts/storybook-account"]}>
|
||||
<Story />
|
||||
</MemoryRouter>
|
||||
),
|
||||
],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"Раздел ближайших событий на странице счёта WealthLedger. Раздел самостоятельно отображает загрузку, ошибку, отсутствие событий и полученные данные. Все события и суммы вымышлены. Ссылка на календарь меняет только локальный маршрут MemoryRouter; сам календарь в этой истории не отображается.",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: {
|
||||
events: {
|
||||
state: "loaded",
|
||||
to: eventsPath,
|
||||
items: [
|
||||
syntheticEvent,
|
||||
{
|
||||
...syntheticEvent,
|
||||
type: "dividend",
|
||||
date: "2026-11-01",
|
||||
dateKind: "registry",
|
||||
ticker: "EXAMPLE",
|
||||
displayName: "Учебные технологии",
|
||||
projectedAmount: { currency: "RUB", value: "1200" },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
} satisfies Meta<typeof RecentEvents>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Loaded: Story = {
|
||||
name: "События получены",
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Предстоящие купоны и дивиденды показываются с ожидаемой суммой. Это прогноз событий, а не подтверждение получения дохода.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Loading: Story = {
|
||||
name: "Загрузка раздела",
|
||||
args: { events: { state: "loading", to: eventsPath } },
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Локальный skeleton занимает место строк событий и имеет доступное обозначение загрузки. Остальные разделы страницы могут оставаться доступными.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Failed: Story = {
|
||||
name: "Ошибка получения событий",
|
||||
args: { events: { state: "error", to: eventsPath } },
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Ошибка ограничена разделом событий. Сохраняется переход к полному календарю; недоступные события не выдаются за пустой список.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Empty: Story = {
|
||||
name: "Нет ближайших событий",
|
||||
args: { events: { state: "empty", to: eventsPath } },
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Успешно полученный пустой результат объясняется отдельным сообщением и сохраняет переход к календарю.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const MissingAmount: Story = {
|
||||
name: "Событие без ожидаемой суммы",
|
||||
args: {
|
||||
events: {
|
||||
state: "loaded",
|
||||
to: eventsPath,
|
||||
items: [{ ...syntheticEvent, projectedAmount: null }],
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Событие остаётся видимым при неизвестной ожидаемой сумме. Отсутствие оценки не подменяется нулевой выплатой.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user