refactor: colocate frontend component files #35
+2
-2
@@ -76,8 +76,8 @@ Add/Edit/Delete; restore/category SVG остаются локальными.
|
||||
|
||||
## Примеры
|
||||
|
||||
- Общая busy-область: существующий [LoadingSkeleton](../packages/ui/src/LoadingSkeleton.tsx), а не domain widget в shared.
|
||||
- Account-income state views: [страница](../src/pages/account-income/ui/AccountIncomePage.tsx) и её flat `components/*.view.tsx`; новый page-local filter остаётся здесь.
|
||||
- Общая busy-область: существующий [LoadingSkeleton](../packages/ui/src/LoadingSkeleton/LoadingSkeleton.tsx), а не domain widget в shared.
|
||||
- Account-income state views: [страница](../src/pages/account-income/ui/AccountIncomePage/AccountIncomePage.tsx) и её `components/`; новый page-local filter остаётся здесь. Комплекты файлов группируются по [UI convention](conventions/ui.md#размещение-файлов-компонента).
|
||||
- Portfolio query: [entity public API](../src/entities/portfolio/index.ts); новая UI-сводка с бизнес-смыслом не становится shared только из-за нескольких экранов.
|
||||
|
||||
## Проверка
|
||||
|
||||
@@ -26,7 +26,7 @@ Stories не достигают application API, auth, VM и query providers д
|
||||
контракт: keyboard activation, доступность действия, local callback. Не повторяй
|
||||
RTL suite и не тестируй внутренности Mantine. Существующий
|
||||
[Button](../../src/shared/ui/Button.stories.tsx) показывает themed control
|
||||
без production wrapper; [LoadingSkeleton](../../packages/ui/src/LoadingSkeleton.stories.tsx)
|
||||
без production wrapper; [LoadingSkeleton](../../packages/ui/src/LoadingSkeleton/LoadingSkeleton.stories.tsx)
|
||||
— значимые busy states.
|
||||
|
||||
`npm run typecheck`, `npm run deps:storybook`, `npm run build:catalog` проверяют
|
||||
|
||||
@@ -45,7 +45,7 @@ Finance: loading/error/empty/loaded, cached snapshot при refetch failure, ret
|
||||
отсутствие старых данных после session/connection switch. ErrorBoundary: test-only
|
||||
throwing route, безопасная ссылка и reset после navigation.
|
||||
|
||||
Примеры: [AuthForm test](../../src/features/auth/ui/AuthForm.test.tsx),
|
||||
Примеры: [AuthForm test](../../src/features/auth/ui/AuthForm/AuthForm.test.tsx),
|
||||
[client test](../../src/shared/api/client.test.ts),
|
||||
[usePortfolio test](../../src/entities/portfolio/api/usePortfolio.test.tsx).
|
||||
Не копируй fixtures/сценарии целиком, если задача затрагивает один исход.
|
||||
|
||||
+29
-6
@@ -12,7 +12,7 @@ Mantine component и общую тему. Для выпадающего выбо
|
||||
Семантический HTML для структуры страницы остаётся уместным.
|
||||
|
||||
Icons ищи у существующего owner (например,
|
||||
[BankOperationIcon](../../src/entities/bank-card/ui/BankOperationIcon.tsx));
|
||||
[BankOperationIcon](../../src/entities/bank-card/ui/BankOperationIcon/BankOperationIcon.tsx));
|
||||
статичные Add/Edit/Delete доступны в `@wealthledger/icons`. Их SVG декоративны
|
||||
по умолчанию; имя action принадлежит кнопке. Standalone meaningful icon получает
|
||||
`aria-hidden={false}`, `role="img"` и доступное имя. Category/kind mappings
|
||||
@@ -56,11 +56,34 @@ retry callbacks, domain grouping и derived presentation data. View получа
|
||||
image fallback) и formatter одного переданного значения. Группировка/доли
|
||||
коллекции готовятся в VM. Перенос fetch во view ради меньшего container нарушает границу.
|
||||
|
||||
Отдельный state/section с самостоятельной responsibility выноси в flat
|
||||
`components/*.view.tsx`. Небольшой tightly-coupled renderer оставляй рядом.
|
||||
Не создавай folder/barrel/test/CSS для каждого view и не дроби по line count.
|
||||
Пример: [AccountIncomePage](../../src/pages/account-income/ui/AccountIncomePage.tsx)
|
||||
и [его VM](../../src/pages/account-income/ui/AccountIncomePage.vm.ts).
|
||||
Отдельный state/section с самостоятельной responsibility выноси в
|
||||
`components/` своего component. Небольшой tightly-coupled renderer оставляй
|
||||
рядом; размер файла сам по себе не требует разделения.
|
||||
Пример: [AccountIncomePage](../../src/pages/account-income/ui/AccountIncomePage/AccountIncomePage.tsx)
|
||||
и [его VM](../../src/pages/account-income/ui/AccountIncomePage/AccountIncomePage.vm.ts).
|
||||
|
||||
## Размещение файлов компонента
|
||||
|
||||
Правило действует в `src` и `packages`: компонент с сопутствующими файлами
|
||||
(view, VM, types, CSS, tests, stories) размещай в папке `Component/`.
|
||||
Сохраняй полные имена файлов: `Component.tsx`, `Component.view.tsx`,
|
||||
`Component.test.tsx`. Создавай только нужные файлы; одиночный компонент
|
||||
оставляй непосредственно в `ui`, `components` или source-каталоге пакета.
|
||||
|
||||
Внутренние части принадлежат папке родителя; для набора state/section views
|
||||
используй её `components/`. Внутри него действует то же правило: отдельная
|
||||
папка объединяет комплект файлов, одиночный view остаётся файлом.
|
||||
Стили и хуки нескольких соседних компонентов остаются у ближайшего общего
|
||||
владельца; не копируй их и не прячь внутрь одного потребителя.
|
||||
|
||||
Папка компонента не создаёт новую FSD-границу. Публичные exports остаются в
|
||||
существующем `index.ts` slice/segment или entry пакета; внутри используй
|
||||
прямые относительные imports без дополнительных barrels на каждый компонент.
|
||||
При переносе обновляй imports, ссылки документации и проверки, зависящие от пути.
|
||||
|
||||
Пример: [BankCardForm](../../src/entities/bank-card/ui/BankCardForm/BankCardForm.tsx)
|
||||
лежит рядом со своим view, тестом и story; общий `BankForms.module.css`
|
||||
остаётся в `bank-card/ui`.
|
||||
|
||||
## Формы
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ module.exports = {
|
||||
severity: "error",
|
||||
from: { path: "\\.stories\\.tsx$|^\\.storybook/preview\\.tsx$" },
|
||||
to: {
|
||||
path: "^src/(shared/api|features/auth|app/routes|app/ui)/|^src/(entities|features)/[^/]+/api/|\\.vm\\.ts$|^src/pages/[^/]+/ui/[^/]+Page\\.tsx$|node_modules/(@tanstack/react-query|openapi-fetch|openapi-react-query)/",
|
||||
path: "^src/(shared/api|features/auth|app/routes|app/ui)/|^src/(entities|features)/[^/]+/api/|\\.vm\\.ts$|^src/pages/[^/]+/ui/.*Page\\.tsx$|node_modules/(@tanstack/react-query|openapi-fetch|openapi-react-query)/",
|
||||
reachable: true,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MantineProvider } from "@mantine/core";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { LoadingSkeleton } from "./LoadingSkeleton";
|
||||
import { LoadingSkeleton } from "../LoadingSkeleton/LoadingSkeleton";
|
||||
import { StateView } from "./StateView";
|
||||
|
||||
describe("StateView", () => {
|
||||
@@ -1,3 +1,3 @@
|
||||
export { EntryCard } from "./EntryCard";
|
||||
export { LoadingSkeleton } from "./LoadingSkeleton";
|
||||
export { StateView } from "./StateView";
|
||||
export { EntryCard } from "./EntryCard/EntryCard";
|
||||
export { LoadingSkeleton } from "./LoadingSkeleton/LoadingSkeleton";
|
||||
export { StateView } from "./StateView/StateView";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { FC } from "react";
|
||||
import { lazy } from "react";
|
||||
import { Navigate, Route, Routes } from "react-router";
|
||||
import { LazyPage } from "./RouteFallback";
|
||||
import { Protected, Public } from "./RouteGuards";
|
||||
import { LazyPage } from "../RouteFallback";
|
||||
import { Protected, Public } from "../RouteGuards";
|
||||
|
||||
const CardPage = lazy(async () => {
|
||||
const { CardPage } = await import("@/pages/card");
|
||||
@@ -65,7 +65,7 @@ const SettingsPage = lazy(async () => {
|
||||
return { default: SettingsPage };
|
||||
});
|
||||
const ProtectedLayout = lazy(async () => {
|
||||
const { ProtectedLayout } = await import("./ProtectedLayout");
|
||||
const { ProtectedLayout } = await import("../ProtectedLayout");
|
||||
return { default: ProtectedLayout };
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { FC } from "react";
|
||||
import { AppBreadcrumbs, AppShell } from "@/app/ui";
|
||||
import { ProtectedDocumentTitle } from "./DocumentTitle";
|
||||
import { ProtectedDocumentTitle } from "./DocumentTitle/DocumentTitle";
|
||||
|
||||
const ProtectedLayout: FC = () => {
|
||||
return (
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export { AppRoutes } from "./AppRoutes";
|
||||
export { RouteErrorBoundary } from "./RouteErrorBoundary";
|
||||
export { AppRoutes } from "./AppRoutes/AppRoutes";
|
||||
export { RouteErrorBoundary } from "./RouteErrorBoundary/RouteErrorBoundary";
|
||||
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
export { AppBreadcrumbs } from "./AppBreadcrumbs";
|
||||
export { AppShell } from "./AppShell";
|
||||
export { AppBreadcrumbs } from "./AppBreadcrumbs/AppBreadcrumbs";
|
||||
export { AppShell } from "./AppShell/AppShell";
|
||||
|
||||
@@ -20,11 +20,11 @@ export {
|
||||
} from "./model/form-validation";
|
||||
export { bankOperationKinds } from "./model/operation-kinds";
|
||||
export { bankPeriod } from "./model/period";
|
||||
export { BankCardFace } from "./ui/BankCardFace";
|
||||
export { BankCardForm } from "./ui/BankCardForm";
|
||||
export { BankCardFace } from "./ui/BankCardFace/BankCardFace";
|
||||
export { BankCardForm } from "./ui/BankCardForm/BankCardForm";
|
||||
export { BankFeedback } from "./ui/BankFeedback";
|
||||
export { BankOperationIcon } from "./ui/BankOperationIcon";
|
||||
export { BankOperationIcon } from "./ui/BankOperationIcon/BankOperationIcon";
|
||||
export { BankPeriodPicker } from "./ui/BankPeriodPicker";
|
||||
export { BankSummaryView } from "./ui/BankSummary.view";
|
||||
export { CategoryManager } from "./ui/CategoryManager";
|
||||
export { BankSummaryView } from "./ui/BankSummary/BankSummary.view";
|
||||
export { CategoryManager } from "./ui/CategoryManager/CategoryManager";
|
||||
export { useBankFormFocus } from "./ui/useBankFormFocus";
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import type { FC } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { formatMoney } from "@/shared/lib";
|
||||
import type { BankCard } from "../api/queries";
|
||||
import type { BankCard } from "../../api/queries";
|
||||
import classes from "./BankCardFace.module.css";
|
||||
|
||||
type BankCardFaceProps = { card: BankCard };
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import type { BankCardValues } from "../model/form-validation";
|
||||
import type { BankCardValues } from "../../model/form-validation";
|
||||
import { BankCardFields } from "./BankCardForm.view";
|
||||
|
||||
const meta = {
|
||||
+1
-1
@@ -6,7 +6,7 @@ import { describe, expect, it, vi } from "vitest";
|
||||
import { configureAuthClient } from "@/shared/api";
|
||||
import { createTestQueryClient } from "@/test/query";
|
||||
import { server } from "@/test/server";
|
||||
import type { BankCard } from "../api/queries";
|
||||
import type { BankCard } from "../../api/queries";
|
||||
import { BankCardForm } from "./BankCardForm";
|
||||
|
||||
const card: BankCard = {
|
||||
+6
-6
@@ -4,18 +4,18 @@ import { type FC, useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { formatDate } from "@/shared/lib";
|
||||
import { useBankMutations } from "../api/mutations";
|
||||
import { type BankCard, useBankCard } from "../api/queries";
|
||||
import { useBankMutations } from "../../api/mutations";
|
||||
import { type BankCard, useBankCard } from "../../api/queries";
|
||||
import {
|
||||
type BankCardValues,
|
||||
bankCardSchema,
|
||||
bankMoneyValue,
|
||||
bankToday,
|
||||
} from "../model/form-validation";
|
||||
} from "../../model/form-validation";
|
||||
import { BankFeedback } from "../BankFeedback";
|
||||
import classes from "../BankForms.module.css";
|
||||
import { useBankFormFocus } from "../useBankFormFocus";
|
||||
import { BankCardFields } from "./BankCardForm.view";
|
||||
import { BankFeedback } from "./BankFeedback";
|
||||
import classes from "./BankForms.module.css";
|
||||
import { useBankFormFocus } from "./useBankFormFocus";
|
||||
|
||||
type BankCardFormProps = { card?: BankCard; onClose: () => void };
|
||||
const BankCardForm: FC<BankCardFormProps> = (props) => {
|
||||
+1
-1
@@ -8,7 +8,7 @@ import {
|
||||
bankDateInputValue,
|
||||
bankDateSchema,
|
||||
bankToday,
|
||||
} from "../model/form-validation";
|
||||
} from "../../model/form-validation";
|
||||
|
||||
type BankCardFieldsProps = { archived: boolean };
|
||||
const BankCardFields: FC<BankCardFieldsProps> = (props) => {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import type { FC } from "react";
|
||||
import { bindIconAnimation } from "@/shared/lib";
|
||||
import type { BankOperation } from "../api/queries";
|
||||
import type { BankOperation } from "../../api/queries";
|
||||
|
||||
import { bankOperationAppearance } from "../model/operation-appearance";
|
||||
import { bankOperationAppearance } from "../../model/operation-appearance";
|
||||
import classes from "./BankOperationIcon.module.css";
|
||||
|
||||
type BankOperationIconProps = {
|
||||
+2
-2
@@ -3,8 +3,8 @@ import { LoadingSkeleton } from "@wealthledger/ui";
|
||||
import type { CSSProperties, FC } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { formatMoney } from "@/shared/lib";
|
||||
import type { BankSummary } from "../api/queries";
|
||||
import { BankOperationIcon } from "./BankOperationIcon";
|
||||
import type { BankSummary } from "../../api/queries";
|
||||
import { BankOperationIcon } from "../BankOperationIcon/BankOperationIcon";
|
||||
import classes from "./BankSummary.module.css";
|
||||
|
||||
type BankSummaryViewProps = {
|
||||
+6
-6
@@ -18,12 +18,12 @@ import {
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { z } from "zod";
|
||||
import { validationMessage } from "@/shared/i18n";
|
||||
import { useBankMutations } from "../api/mutations";
|
||||
import { type ExpenseCategory, useBankCategories } from "../api/queries";
|
||||
import { BankFeedback } from "./BankFeedback";
|
||||
import classes from "./BankForms.module.css";
|
||||
import { BankOperationIcon } from "./BankOperationIcon";
|
||||
import { useBankFormFocus } from "./useBankFormFocus";
|
||||
import { useBankMutations } from "../../api/mutations";
|
||||
import { type ExpenseCategory, useBankCategories } from "../../api/queries";
|
||||
import { BankFeedback } from "../BankFeedback";
|
||||
import classes from "../BankForms.module.css";
|
||||
import { BankOperationIcon } from "../BankOperationIcon/BankOperationIcon";
|
||||
import { useBankFormFocus } from "../useBankFormFocus";
|
||||
|
||||
const MAX_CATEGORY_NAME_LENGTH = 80;
|
||||
|
||||
@@ -8,4 +8,4 @@ export {
|
||||
type BrokerageAccountCard,
|
||||
brokerageAccountCards,
|
||||
} from "./model/display";
|
||||
export { BrokerageAccountList } from "./ui/BrokerageAccountList";
|
||||
export { BrokerageAccountList } from "./ui/BrokerageAccountList/BrokerageAccountList";
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { MemoryRouter } from "react-router";
|
||||
import type { BrokerageAccount } from "../api/useBrokerageAccounts";
|
||||
import { brokerageAccountCards } from "../model/display";
|
||||
import type { BrokerageAccount } from "../../api/useBrokerageAccounts";
|
||||
import { brokerageAccountCards } from "../../model/display";
|
||||
import { BrokerageAccountList } from "./BrokerageAccountList";
|
||||
|
||||
const syntheticAccount = {
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { MantineProvider } from "@mantine/core";
|
||||
import { render, screen, within } from "@testing-library/react";
|
||||
import { MemoryRouter } from "react-router";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { brokerageAccountCards } from "../model/display";
|
||||
import { brokerageAccountCards } from "../../model/display";
|
||||
import { BrokerageAccountList } from "./BrokerageAccountList";
|
||||
|
||||
describe("BrokerageAccountList", () => {
|
||||
+2
-2
@@ -3,8 +3,8 @@ import type { FC } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router";
|
||||
import { formatDate, formatMoney } from "@/shared/lib";
|
||||
import type { BrokerageAccountCard } from "../model/display";
|
||||
import { accountTypeKey } from "../model/display";
|
||||
import type { BrokerageAccountCard } from "../../model/display";
|
||||
import { accountTypeKey } from "../../model/display";
|
||||
import classes from "./BrokerageAccountList.module.css";
|
||||
|
||||
type BrokerageAccountListProps = { accounts: BrokerageAccountCard[] };
|
||||
@@ -6,4 +6,4 @@ export { BrokerageEventCard } from "./ui/BrokerageEventCard";
|
||||
export {
|
||||
BrokerageEventsPreview,
|
||||
type BrokerageEventsPreviewState,
|
||||
} from "./ui/BrokerageEventsPreview";
|
||||
} from "./ui/BrokerageEventsPreview/BrokerageEventsPreview";
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { MemoryRouter } from "react-router";
|
||||
import type { BrokerageEvent } from "../api/useBrokerageEvents";
|
||||
import type { BrokerageEvent } from "../../api/useBrokerageEvents";
|
||||
import { BrokerageEventsPreview } from "./BrokerageEventsPreview";
|
||||
|
||||
const syntheticEvent = {
|
||||
+2
-2
@@ -3,8 +3,8 @@ import { LoadingSkeleton } from "@wealthledger/ui";
|
||||
import type { FC } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router";
|
||||
import type { BrokerageEvent } from "../api/useBrokerageEvents";
|
||||
import { BrokerageEventCard } from "./BrokerageEventCard";
|
||||
import type { BrokerageEvent } from "../../api/useBrokerageEvents";
|
||||
import { BrokerageEventCard } from "../BrokerageEventCard";
|
||||
|
||||
type BrokerageEventsPreviewProps = {
|
||||
events: BrokerageEventsPreviewState;
|
||||
@@ -1,4 +1,4 @@
|
||||
export { AuthProvider, useAuth } from "./model/auth";
|
||||
export { AuthPageLayout } from "./ui/AuthPageLayout";
|
||||
export { AuthPageLayout } from "./ui/AuthPageLayout/AuthPageLayout";
|
||||
export { LoginForm } from "./ui/LoginForm";
|
||||
export { RegisterForm } from "./ui/RegisterForm";
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
type AuthFormValues,
|
||||
loginSchema,
|
||||
registerSchema,
|
||||
} from "../model/validation";
|
||||
} from "../../model/validation";
|
||||
import classes from "./AuthForm.module.css";
|
||||
|
||||
type AuthFormProps = {
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { FC } from "react";
|
||||
import { useLocation, useNavigate } from "react-router";
|
||||
import { useAuth } from "../model/auth";
|
||||
import { AuthForm } from "./AuthForm";
|
||||
import { AuthForm } from "./AuthForm/AuthForm";
|
||||
|
||||
const LoginForm: FC = () => {
|
||||
const { login } = useAuth();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { FC } from "react";
|
||||
import { useLocation, useNavigate } from "react-router";
|
||||
import { useAuth } from "../model/auth";
|
||||
import { AuthForm } from "./AuthForm";
|
||||
import { AuthForm } from "./AuthForm/AuthForm";
|
||||
|
||||
const RegisterForm: FC = () => {
|
||||
const { register } = useAuth();
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { TbankConnectionSection } from "./ui/TbankConnectionSection";
|
||||
export { TbankConnectionSection } from "./ui/TbankConnectionSection/TbankConnectionSection";
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { useAuthenticatedQuery } from "@/shared/api";
|
||||
import { tbankConnectionQueryOptions } from "../model/connection-boundary";
|
||||
import { tbankConnectionQueryOptions } from "../../model/connection-boundary";
|
||||
|
||||
function useTbankConnectionViewModel() {
|
||||
const status = useAuthenticatedQuery({
|
||||
+1
-1
@@ -15,7 +15,7 @@ import { apiErrorCode, apiQueryClient } from "@/shared/api";
|
||||
import {
|
||||
commitTbankConnectionBoundary,
|
||||
type TbankConnectionStatus,
|
||||
} from "../model/connection-boundary";
|
||||
} from "../../model/connection-boundary";
|
||||
|
||||
type TbankConnectionSectionLoadedProps = {
|
||||
status: TbankConnectionStatus;
|
||||
@@ -1 +1 @@
|
||||
export { AccountEventsPage } from "./ui/AccountEventsPage";
|
||||
export { AccountEventsPage } from "./ui/AccountEventsPage/AccountEventsPage";
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { AccountIncomePage } from "./ui/AccountIncomePage";
|
||||
export { AccountIncomePage } from "./ui/AccountIncomePage/AccountIncomePage";
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import type { IncomeAnalytics } from "@/entities/income";
|
||||
import { configureAuthClient } from "@/shared/api";
|
||||
import { createQueryWrapper } from "@/test/query";
|
||||
import { server } from "@/test/server";
|
||||
import { isDate } from "../model/period";
|
||||
import { isDate } from "../../model/period";
|
||||
import { AccountIncomePage } from "./AccountIncomePage";
|
||||
import { toIncomeDisplayModel } from "./AccountIncomePage.vm";
|
||||
import { IncomePayments } from "./components/IncomePayments.view";
|
||||
+1
-1
@@ -13,7 +13,7 @@ import {
|
||||
isDate,
|
||||
moscowDate,
|
||||
parseDraftDate,
|
||||
} from "../model/period";
|
||||
} from "../../model/period";
|
||||
|
||||
const ISO_MONTH_LENGTH = 7;
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import classes from "../AccountIncomePage.module.css";
|
||||
import type { AccountIncomePageViewModel } from "../AccountIncomePage.vm";
|
||||
import { IncomeComparisons } from "./IncomeComparisons.view";
|
||||
import { IncomePayments } from "./IncomePayments.view";
|
||||
import { IncomePeriodForm } from "./IncomePeriodForm.view";
|
||||
import { IncomePeriodForm } from "./IncomePeriodForm/IncomePeriodForm.view";
|
||||
import { IncomeSummary } from "./IncomeSummary.view";
|
||||
|
||||
type LoadedProps = Extract<AccountIncomePageViewModel, { state: "loaded" }>;
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import type { FC } from "react";
|
||||
import { FormProvider, useForm, useFormState } from "react-hook-form";
|
||||
import type { IncomeForm } from "../../model/period";
|
||||
import type { IncomeForm } from "../../../../model/period";
|
||||
import { IncomePeriodForm } from "./IncomePeriodForm.view";
|
||||
|
||||
const period = { from: "01.08.2026", to: "27.08.2026" };
|
||||
+2
-2
@@ -8,8 +8,8 @@ import {
|
||||
type IncomeForm,
|
||||
moscowDate,
|
||||
parseDraftDate,
|
||||
} from "../../model/period";
|
||||
import classes from "../AccountIncomePage.module.css";
|
||||
} from "../../../../model/period";
|
||||
import classes from "../../AccountIncomePage.module.css";
|
||||
|
||||
type IncomePeriodFormProps = {
|
||||
onSubmit: FormEventHandler<HTMLFormElement>;
|
||||
@@ -1 +1 @@
|
||||
export { AccountOperationsPage } from "./ui/AccountOperationsPage";
|
||||
export { AccountOperationsPage } from "./ui/AccountOperationsPage/AccountOperationsPage";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user