diff --git a/src/pages/account-events/ui/AccountEventsPage/AccountEventsPage.filters.test.tsx b/src/pages/account-events/ui/AccountEventsPage/AccountEventsPage.filters.test.tsx
index 4968f31..fbc7a51 100644
--- a/src/pages/account-events/ui/AccountEventsPage/AccountEventsPage.filters.test.tsx
+++ b/src/pages/account-events/ui/AccountEventsPage/AccountEventsPage.filters.test.tsx
@@ -18,7 +18,7 @@ import {
useLocation,
useNavigate,
} from "react-router";
-import { describe, expect, it, vi } from "vitest";
+import { beforeEach, describe, expect, it, vi } from "vitest";
import { configureAuthClient } from "@/shared/api";
import { createTestQueryClient } from "@/test/query";
@@ -47,13 +47,40 @@ const Navigation: FC = () => {
);
};
+function renderEvents(accountId: string, searches: string[]) {
+ return render(
+
+
+
+ `/accounts/${accountId}/events${search}`,
+ )}
+ initialIndex={0}
+ >
+
+
+
+ }
+ path="/accounts/:accountId/events"
+ />
+
+
+
+ ,
+ );
+}
+
describe("Upcoming event date filters", () => {
- it("keeps reads and sync disabled without an account scope", async () => {
+ beforeEach(() => {
configureAuthClient({
accessToken: () => "token",
clear: vi.fn(),
refresh: () => Promise.resolve(true),
});
+ });
+
+ it("keeps reads and sync disabled without an account scope", async () => {
const requests: string[] = [];
server.use(
http.all("*/api/v1/*", ({ request }) => {
@@ -87,11 +114,6 @@ describe("Upcoming event date filters", () => {
])(
"keeps event calendar dates in GET and source sync requests: %s",
async (search) => {
- configureAuthClient({
- accessToken: () => "token",
- clear: vi.fn(),
- refresh: () => Promise.resolve(true),
- });
const requested: string[] = [];
const syncRequests: unknown[] = [];
server.use(
@@ -153,11 +175,6 @@ describe("Upcoming event date filters", () => {
it.each(["account-1", "all"])(
"normalizes invalid links and history while preserving one-sided future dates for %s",
async (accountId) => {
- configureAuthClient({
- accessToken: () => "token",
- clear: vi.fn(),
- refresh: () => Promise.resolve(true),
- });
const searches: string[] = [];
server.use(
http.get(
@@ -169,31 +186,13 @@ describe("Upcoming event date filters", () => {
},
),
);
- render(
-
-
- `/accounts/${accountId}/events${search}`)}
- initialIndex={0}
- >
-
-
-
- }
- path="/accounts/:accountId/events"
- />
-
-
-
- ,
- );
+ renderEvents(accountId, [
+ "?from=bad&to=2099-02-28",
+ "?from=2099-02-30",
+ "?from=2099-03-01&to=2099-02-28",
+ "?from=2099-02-01",
+ "?to=2099-02-28",
+ ]);
await screen.findByLabelText("Период");
for (const expected of ["", "", "?from=2099-02-01", "?to=2099-02-28"]) {
@@ -221,11 +220,6 @@ describe("Upcoming event date filters", () => {
it.each(["account-1", "all"])(
"lets users reset filters after a request failure for %s",
async (accountId) => {
- configureAuthClient({
- accessToken: () => "token",
- clear: vi.fn(),
- refresh: () => Promise.resolve(true),
- });
server.use(
http.get(
"*/api/v1/brokerage-accounts/:accountId/events",
@@ -235,24 +229,7 @@ describe("Upcoming event date filters", () => {
: HttpResponse.json(resource({ events: [] })),
),
);
- render(
-
-
-
-
-
-
- }
- path="/accounts/:accountId/events"
- />
-
-
-
- ,
- );
+ renderEvents(accountId, ["?from=2099-02-01"]);
await screen.findByRole("button", { name: "Повторить" });
fireEvent.click(screen.getByRole("button", { name: "Сбросить" }));
await screen.findByLabelText("Период");
@@ -263,11 +240,6 @@ describe("Upcoming event date filters", () => {
it.each(["account-1", "all"])(
"applies dates only on submit, restores URL dates, and resets from empty results for %s",
async (accountId) => {
- configureAuthClient({
- accessToken: () => "token",
- clear: vi.fn(),
- refresh: () => Promise.resolve(true),
- });
const searches: string[] = [];
server.use(
http.get(
@@ -286,26 +258,7 @@ describe("Upcoming event date filters", () => {
},
),
);
- render(
-
-
-
-
-
-
- }
- path="/accounts/:accountId/events"
- />
-
-
-
- ,
- );
+ renderEvents(accountId, ["?from=2099-02-01&to=2099-02-28"]);
const from = await screen.findByLabelText("Период");
expect(from).toHaveTextContent("01.02.2099 – 28.02.2099");
expect(screen.getByRole("button", { name: "Применить" })).toBeDisabled();
diff --git a/src/pages/account-events/ui/AccountEventsPage/AccountEventsPage.vm.ts b/src/pages/account-events/ui/AccountEventsPage/AccountEventsPage.vm.ts
index 20d0a67..e839d83 100644
--- a/src/pages/account-events/ui/AccountEventsPage/AccountEventsPage.vm.ts
+++ b/src/pages/account-events/ui/AccountEventsPage/AccountEventsPage.vm.ts
@@ -11,13 +11,11 @@ import { isValidPeriod } from "@/shared/lib";
type AccountEventsPageViewModel
= | {
canApply: boolean;
- draftFrom: null | string;
- draftTo: null | string;
+ draftPeriod: [null | string, null | string];
events: BrokerageEvent[];
lastSuccessfulAt?: null | string;
onApply: () => void;
- onDraftFromChange: (value: null | string) => void;
- onDraftToChange: (value: null | string) => void;
+ onPeriodChange: (value: [null | string, null | string]) => void;
onReset: () => void;
partial?: boolean;
refreshError: boolean;
@@ -47,8 +45,12 @@ function useAccountEventsPageViewModel(
? urlTo
: null;
- const [draftFrom, setDraftFrom] = useState(appliedFrom);
- const [draftTo, setDraftTo] = useState(appliedTo);
+ const [draftPeriod, setDraftPeriod] = useState<[
+ null | string,
+ null | string,
+ ]>([appliedFrom, appliedTo]);
+
+ const [draftFrom, draftTo] = draftPeriod;
useEffect(() => {
if (isValidUrlPeriod) return;
const normalized = new URLSearchParams(searchParameters);
@@ -64,8 +66,7 @@ function useAccountEventsPageViewModel(
if (previousPeriod[0] !== appliedFrom || previousPeriod[1] !== appliedTo) {
setPreviousPeriod([appliedFrom, appliedTo]);
- setDraftFrom(appliedFrom);
- setDraftTo(appliedTo);
+ setDraftPeriod([appliedFrom, appliedTo]);
}
const events = useBrokerageEvents(accountId, {
@@ -86,8 +87,7 @@ function useAccountEventsPageViewModel(
if (events.isLoading) return { state: "loading" };
const onReset = () => {
- setDraftFrom(null);
- setDraftTo(null);
+ setDraftPeriod([null, null]);
setSearchParameters({});
};
@@ -105,8 +105,7 @@ function useAccountEventsPageViewModel(
canApply:
(draftFrom !== appliedFrom || draftTo !== appliedTo)
&& isValidPeriod(draftFrom, draftTo),
- draftFrom,
- draftTo,
+ draftPeriod,
events: events.data.events,
lastSuccessfulAt: events.meta?.lastSuccessfulAt,
onApply: () => {
@@ -116,8 +115,7 @@ function useAccountEventsPageViewModel(
...(draftTo && { to: draftTo }),
});
},
- onDraftFromChange: setDraftFrom,
- onDraftToChange: setDraftTo,
+ onPeriodChange: setDraftPeriod,
onReset,
partial: events.meta?.availability !== "complete",
refreshError: events.isError || sync.sourceError || sync.transportError,
diff --git a/src/pages/account-events/ui/AccountEventsPage/components/AccountEventsPageLoaded.view.tsx b/src/pages/account-events/ui/AccountEventsPage/components/AccountEventsPageLoaded.view.tsx
index 8956252..362a84f 100644
--- a/src/pages/account-events/ui/AccountEventsPage/components/AccountEventsPageLoaded.view.tsx
+++ b/src/pages/account-events/ui/AccountEventsPage/components/AccountEventsPageLoaded.view.tsx
@@ -10,6 +10,7 @@ import {
Title,
} from "@mantine/core";
import { DatePickerInput } from "@mantine/dates";
+import { useTranslation } from "react-i18next";
import { BrokerageEventCard } from "@/entities/brokerage-event";
import { formatSnapshotTime } from "@/shared/lib";
@@ -17,7 +18,6 @@ import { formatSnapshotTime } from "@/shared/lib";
import type { AccountEventsPageViewModel } from "../AccountEventsPage.vm";
import { AccountEventsPageEmpty } from "./AccountEventsPageEmpty.view";
-import { useAccountEventsPageLoadedVm } from "./AccountEventsPageLoaded.vm";
type AccountEventsPageLoadedProps = Extract<
AccountEventsPageViewModel,
@@ -56,7 +56,7 @@ const AccountEventsPageLoadedEvents: FC = (
};
const AccountEventsPageLoaded: FC = (props) => {
- const { onPeriodChange, t } = useAccountEventsPageLoadedVm(props);
+ const { t } = useTranslation();
return (
@@ -100,13 +100,13 @@ const AccountEventsPageLoaded: FC = (props) => {
clearable
clearButtonProps={{ "aria-label": t("ledger.clearPeriod") }}
label={t("ledger.period")}
- onChange={onPeriodChange}
+ onChange={props.onPeriodChange}
popoverProps={{
middlewares: { shift: { crossAxis: true } },
returnFocus: true,
}}
type="range"
- value={[props.draftFrom, props.draftTo]}
+ value={props.draftPeriod}
valueFormat="DD.MM.YYYY"
/>
diff --git a/src/pages/account-events/ui/AccountEventsPage/components/AccountEventsPageLoaded.vm.ts b/src/pages/account-events/ui/AccountEventsPage/components/AccountEventsPageLoaded.vm.ts
deleted file mode 100644
index af03a32..0000000
--- a/src/pages/account-events/ui/AccountEventsPage/components/AccountEventsPageLoaded.vm.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { useTranslation } from "react-i18next";
-
-import type { AccountEventsPageViewModel } from "../AccountEventsPage.vm";
-
-type AccountEventsPageLoadedProps = Extract<
- AccountEventsPageViewModel,
- { state: "loaded" }
->;
-
-function useAccountEventsPageLoadedVm(props: AccountEventsPageLoadedProps) {
- const { t } = useTranslation();
-
- const onPeriodChange: (value: [null | string, null | string]) => void = ([
- from,
- to,
- ]) => {
- props.onDraftFromChange(from);
- props.onDraftToChange(to);
- };
-
- return { onPeriodChange, t };
-}
-
-export { useAccountEventsPageLoadedVm };
diff --git a/src/pages/account-operations/ui/AccountOperationsPage/AccountOperationsPage.vm.ts b/src/pages/account-operations/ui/AccountOperationsPage/AccountOperationsPage.vm.ts
index ed1676b..e3b3c6a 100644
--- a/src/pages/account-operations/ui/AccountOperationsPage/AccountOperationsPage.vm.ts
+++ b/src/pages/account-operations/ui/AccountOperationsPage/AccountOperationsPage.vm.ts
@@ -13,22 +13,22 @@ import { useScreenSync } from "@/features/tbank-connection";
import { ApiErrorCode, apiErrorCode, isApiErrorCode } from "@/shared/api";
import { isValidPeriod } from "@/shared/lib";
+const operationCategorySet = new Set(operationCategories);
+
type AccountOperationsPageViewModel
= | {
canApply: boolean;
draftCategories: OperationCategory[];
- draftFrom: null | string;
- draftTo: null | string;
+ draftPeriod: [null | string, null | string];
hasNext: boolean;
hasPrevious: boolean;
historyLoading?: boolean;
items: BrokerageOperation[];
lastSuccessfulAt?: null | string;
onApply: () => void;
- onDraftCategoriesChange: (value: OperationCategory[]) => void;
- onDraftFromChange: (value: null | string) => void;
- onDraftToChange: (value: null | string) => void;
+ onCategoriesChange: (value: string[]) => void;
onNext: () => void;
+ onPeriodChange: (value: [null | string, null | string]) => void;
onPrevious: () => void;
onReset: () => void;
partial?: boolean;
@@ -64,8 +64,12 @@ const useAccountOperationsPageVm = (
(searchParameters.get("categories") ?? "").split(",").includes(category),
);
- const [draftFrom, setDraftFrom] = useState(appliedFrom);
- const [draftTo, setDraftTo] = useState(appliedTo);
+ const [draftPeriod, setDraftPeriod] = useState<[
+ null | string,
+ null | string,
+ ]>([appliedFrom, appliedTo]);
+
+ const [draftFrom, draftTo] = draftPeriod;
const [draftCategories, setDraftCategories]
= useState(appliedCategories);
@@ -100,15 +104,8 @@ const useAccountOperationsPageVm = (
if (previousSearch !== searchParameters) {
setPreviousSearch(searchParameters);
- setDraftFrom(appliedFrom);
- setDraftTo(appliedTo);
- setDraftCategories(
- operationCategories.filter(category =>
- (searchParameters.get("categories") ?? "")
- .split(",")
- .includes(category),
- ),
- );
+ setDraftPeriod([appliedFrom, appliedTo]);
+ setDraftCategories(appliedCategories);
}
const firstPageQuery = {
@@ -154,8 +151,7 @@ const useAccountOperationsPageVm = (
};
const onReset = () => {
- setDraftFrom(null);
- setDraftTo(null);
+ setDraftPeriod([null, null]);
setDraftCategories([]);
setSearchParameters({});
resetCursors();
@@ -182,8 +178,7 @@ const useAccountOperationsPageVm = (
return {
canApply: isDirty && isValidPeriod(draftFrom, draftTo),
draftCategories,
- draftFrom,
- draftTo,
+ draftPeriod,
hasNext: Boolean(nextCursor && operations.data.hasNext),
hasPrevious: cursors.length > 0,
historyLoading:
@@ -202,13 +197,16 @@ const useAccountOperationsPageVm = (
});
resetCursors();
},
- onDraftCategoriesChange: setDraftCategories,
- onDraftFromChange: setDraftFrom,
- onDraftToChange: setDraftTo,
+ onCategoriesChange: values => setDraftCategories(
+ values.filter((value): value is OperationCategory =>
+ operationCategorySet.has(value),
+ ),
+ ),
onNext: () => {
if (nextCursor)
setPagination({ cursors: [...cursors, nextCursor], scopeKey });
},
+ onPeriodChange: setDraftPeriod,
onPrevious: () =>
setPagination({ cursors: cursors.slice(0, -1), scopeKey }),
onReset,
diff --git a/src/pages/account-operations/ui/AccountOperationsPage/components/AccountOperationsPageLoaded.view.tsx b/src/pages/account-operations/ui/AccountOperationsPage/components/AccountOperationsPageLoaded.view.tsx
index c981e79..af02e2d 100644
--- a/src/pages/account-operations/ui/AccountOperationsPage/components/AccountOperationsPageLoaded.view.tsx
+++ b/src/pages/account-operations/ui/AccountOperationsPage/components/AccountOperationsPageLoaded.view.tsx
@@ -14,13 +14,11 @@ import { DatePickerInput } from "@mantine/dates";
import { StateView } from "@wealthledger/ui";
import { useTranslation } from "react-i18next";
-import { LedgerEntryRow } from "@/entities/broker-operation";
+import { LedgerEntryRow, operationCategories } from "@/entities/broker-operation";
import { formatSnapshotTime } from "@/shared/lib";
import type { AccountOperationsPageViewModel } from "../AccountOperationsPage.vm";
-import { useAccountOperationsPageLoadedVm } from "./AccountOperationsPageLoaded.vm";
-
type AccountOperationsPageLoadedProps = Extract<
AccountOperationsPageViewModel,
{ state: "loaded" }
@@ -56,22 +54,12 @@ const AccountOperationsPageLoadedOperations: FC<
const AccountOperationsPageLoaded: FC = (
props,
) => {
- const {
- canApply,
- categoryData,
- draftCategories,
- draftFrom,
- draftTo,
- hasNext,
- hasPrevious,
- onApply,
- onCategoriesChange,
- onNext,
- onPeriodChange,
- onPrevious,
- onReset,
- t,
- } = useAccountOperationsPageLoadedVm(props);
+ const { t } = useTranslation();
+
+ const categoryData = operationCategories.map(category => ({
+ label: t(`ledger.category.${category}`),
+ value: category,
+ }));
return (
@@ -115,13 +103,13 @@ const AccountOperationsPageLoaded: FC = (
clearable
clearButtonProps={{ "aria-label": t("ledger.clearPeriod") }}
label={t("ledger.period")}
- onChange={onPeriodChange}
+ onChange={props.onPeriodChange}
popoverProps={{
middlewares: { shift: { crossAxis: true } },
returnFocus: true,
}}
type="range"
- value={[draftFrom, draftTo]}
+ value={props.draftPeriod}
valueFormat="DD.MM.YYYY"
/>
@@ -131,30 +119,30 @@ const AccountOperationsPageLoaded: FC = (
clearButtonProps={{ "aria-label": t("ledger.clearPeriod") }}
data={categoryData}
label={t("ledger.categories")}
- onChange={onCategoriesChange}
+ onChange={props.onCategoriesChange}
placeholder={t("ledger.categoriesPlaceholder")}
- value={draftCategories}
+ value={props.draftCategories}
/>
-
- {!!(hasNext || hasPrevious) && (
+ {!!(props.hasNext || props.hasPrevious) && (
-
+
{t("ledger.previous")}
-
+
{t("ledger.next")}
diff --git a/src/pages/account-operations/ui/AccountOperationsPage/components/AccountOperationsPageLoaded.vm.ts b/src/pages/account-operations/ui/AccountOperationsPage/components/AccountOperationsPageLoaded.vm.ts
deleted file mode 100644
index 5ee01cc..0000000
--- a/src/pages/account-operations/ui/AccountOperationsPage/components/AccountOperationsPageLoaded.vm.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import { useTranslation } from "react-i18next";
-
-import {
- operationCategories,
- type OperationCategory,
-} from "@/entities/broker-operation";
-
-import type { AccountOperationsPageViewModel } from "../AccountOperationsPage.vm";
-
-type AccountOperationsPageLoadedProps = Extract<
- AccountOperationsPageViewModel,
- { state: "loaded" }
->;
-
-const operationCategorySet = new Set(operationCategories);
-
-function fromMultiSelectValue(value: string[]) {
- return value.filter((item): item is OperationCategory =>
- operationCategorySet.has(item),
- );
-}
-
-function useAccountOperationsPageLoadedVm(
- props: AccountOperationsPageLoadedProps,
-) {
- const {
- canApply,
- draftCategories,
- draftFrom,
- draftTo,
- hasNext,
- hasPrevious,
- onApply,
- onDraftCategoriesChange,
- onDraftFromChange,
- onDraftToChange,
- onNext,
- onPrevious,
- onReset,
- } = props;
-
- const { t } = useTranslation();
-
- const categoryData = operationCategories.map(category => ({
- label: t(`ledger.category.${category}`),
- value: category,
- }));
-
- const onPeriodChange: (value: [null | string, null | string]) => void = ([
- from,
- to,
- ]) => {
- onDraftFromChange(from);
- onDraftToChange(to);
- };
-
- const onCategoriesChange: (value: string[]) => void = value =>
- onDraftCategoriesChange(fromMultiSelectValue(value));
-
- return {
- canApply,
- categoryData,
- draftCategories,
- draftFrom,
- draftTo,
- hasNext,
- hasPrevious,
- onApply,
- onCategoriesChange,
- onNext,
- onPeriodChange,
- onPrevious,
- onReset,
- t,
- };
-}
-
-export { useAccountOperationsPageLoadedVm };
diff --git a/src/pages/cards/ui/CardsPage/CardsPage.view.tsx b/src/pages/cards/ui/CardsPage/CardsPage.view.tsx
index 1b1ea0b..a59d1f4 100644
--- a/src/pages/cards/ui/CardsPage/CardsPage.view.tsx
+++ b/src/pages/cards/ui/CardsPage/CardsPage.view.tsx
@@ -27,14 +27,12 @@ import {
import type { CardsPageVm } from "./CardsPage.vm";
import classes from "./CardsPage.module.css";
-import { useCardsPageViewVm } from "./CardsPageView.vm";
type CardsPageViewProps = { vm: CardsPageVm };
const CardsPageViewCards: FC = (props) => {
const { t } = useTranslation();
const { vm } = props;
- const { onAddCard } = useCardsPageViewVm(props);
if (vm.items) {
if (vm.items.length > 0) {
@@ -59,7 +57,7 @@ const CardsPageViewCards: FC = (props) => {
return (
{t("bank.addCard")}}
+ action={{t("bank.addCard")}}
text={text}
title={t("bank.empty")}
/>
@@ -80,16 +78,8 @@ const CardsPageViewCards: FC = (props) => {
};
const CardsPageView: FC = (props) => {
- const {
- onAddCard,
- onArchiveChange,
- onCategories,
- retryCards,
- retryCategories,
- retrySummary,
- t,
- vm,
- } = useCardsPageViewVm(props);
+ const { vm } = props;
+ const { t } = useTranslation();
return (
@@ -98,7 +88,7 @@ const CardsPageView: FC = (props) => {
= (props) => {
@@ -119,7 +109,7 @@ const CardsPageView: FC = (props) => {
{t(vm.items ? "bank.refreshError" : "bank.error")}
-
+
{t("bank.retry")}
@@ -134,7 +124,7 @@ const CardsPageView: FC = (props) => {
}
- onClick={onCategories}
+ onClick={vm.onCategories}
variant="subtle"
>
{t("bank.categories")}
@@ -148,7 +138,7 @@ const CardsPageView: FC = (props) => {
error={vm.summary.isError}
fetching={vm.summary.isFetching}
loading={vm.summary.isLoading}
- retry={retrySummary}
+ retry={vm.retrySummary}
/>
{vm.categories.isError && (
@@ -156,7 +146,7 @@ const CardsPageView: FC = (props) => {
cached={Boolean(vm.categories.data)}
error={vm.categories.error}
loadingError
- retry={retryCategories}
+ retry={vm.retryCategories}
/>
)}
diff --git a/src/pages/cards/ui/CardsPage/CardsPage.vm.ts b/src/pages/cards/ui/CardsPage/CardsPage.vm.ts
index 5cf848c..b7d3e05 100644
--- a/src/pages/cards/ui/CardsPage/CardsPage.vm.ts
+++ b/src/pages/cards/ui/CardsPage/CardsPage.vm.ts
@@ -1,3 +1,5 @@
+import type { ChangeEvent } from "react";
+
import { useState } from "react";
import { useSearchParams } from "react-router";
@@ -32,10 +34,14 @@ function useCardsPageVm() {
to: `/cards/${card.id}?${new URLSearchParams(period)}`,
})),
managingCategories,
+ onAddCard: () => setAdding(true),
+ onArchiveChange: (event: ChangeEvent) =>
+ setArchive(event.currentTarget.checked),
+ onCategories: () => setManagingCategories(true),
period,
- setAdding,
- setArchive,
- setManagingCategories,
+ retryCards: () => void cards.refetch(),
+ retryCategories: () => void categories.refetch(),
+ retrySummary: () => void summary.refetch(),
setPeriod: (value: [null | string, null | string]) => {
if (value[0] && value[1]) setParameters({ from: value[0], to: value[1] });
},
diff --git a/src/pages/cards/ui/CardsPage/CardsPageView.vm.ts b/src/pages/cards/ui/CardsPage/CardsPageView.vm.ts
deleted file mode 100644
index 6a8ef4a..0000000
--- a/src/pages/cards/ui/CardsPage/CardsPageView.vm.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import type { ComponentProps } from "react";
-
-import { Switch } from "@mantine/core";
-import { useTranslation } from "react-i18next";
-
-import type { CardsPageVm } from "./CardsPage.vm";
-
-type CardsPageViewProps = { vm: CardsPageVm };
-
-function useCardsPageViewVm(props: CardsPageViewProps) {
- const { vm } = props;
- const { t } = useTranslation();
- const onAddCard = () => vm.setAdding(true);
-
- const onArchiveChange: ComponentProps["onChange"] = event =>
- vm.setArchive(event.currentTarget.checked);
-
- const retryCards = () => void vm.cards.refetch();
- const onCategories = () => vm.setManagingCategories(true);
- const retrySummary = () => void vm.summary.refetch();
- const retryCategories = () => void vm.categories.refetch();
-
- return {
- onAddCard,
- onArchiveChange,
- onCategories,
- retryCards,
- retryCategories,
- retrySummary,
- t,
- vm,
- };
-}
-
-export { useCardsPageViewVm };