From 9ce112fd6358dfb03f48ff8783db6990269a302b Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Tue, 15 Apr 2025 10:59:56 +0400 Subject: [PATCH] fix: cards fetch optimization --- src/client/index.ts | 1 + src/client/models/CardSummaryResponse.ts | 2 + src/client/models/GetCardSummariesRequest.ts | 16 +++ src/client/services/CardService.ts | 16 ++- .../CardAttributesInSummaryItem.tsx | 6 +- .../CardsPageHeader/CardsPageHeader.tsx | 2 +- .../components/CardsTable/CardsTable.tsx | 102 ++++++++++++------ .../CardsPage/contexts/CardPageContext.tsx | 4 +- .../CardsPage/contexts/PrefillCardContext.tsx | 8 +- .../CardPrefillDrawer/CardPrefillDrawer.tsx | 61 +---------- .../CardPrefillDrawerContent.tsx | 78 ++++++++++++++ .../tables/CardsTable/CardsTable.tsx | 67 +++++++----- .../hooks/usePrefillCard.tsx | 90 ++++++++-------- .../CardsPage/hooks/useCardSummaries.tsx | 64 +++++++---- .../CardsPage/hooks/useCardsPageState.tsx | 77 ------------- .../CardsPage/hooks/useCardsTableForm.tsx | 39 +++++++ .../modals/CardsTableFiltersModal.tsx | 12 +-- src/pages/CardsPage/ui/CardsPage.tsx | 28 ++--- .../CardsTablePreview/CardsTablePreview.tsx | 47 ++++++++ .../components/CardsTablePreview/columns.tsx | 56 ++++++++++ .../modals/ShippingWarehouseForm.tsx | 54 ++++------ .../ui/ShippingWarehousesPage.tsx | 17 +-- 22 files changed, 523 insertions(+), 324 deletions(-) create mode 100644 src/client/models/GetCardSummariesRequest.ts create mode 100644 src/pages/CardsPage/drawers/CardPrefillDrawer/components/CardPrefillDrawerContent/CardPrefillDrawerContent.tsx delete mode 100644 src/pages/CardsPage/hooks/useCardsPageState.tsx create mode 100644 src/pages/CardsPage/hooks/useCardsTableForm.tsx create mode 100644 src/pages/ShippingWarehousesPage/components/CardsTablePreview/CardsTablePreview.tsx create mode 100644 src/pages/ShippingWarehousesPage/components/CardsTablePreview/columns.tsx diff --git a/src/client/index.ts b/src/client/index.ts index f10d6ba..765832d 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -252,6 +252,7 @@ export type { GetBoardsResponse } from './models/GetBoardsResponse'; export type { GetCardBillById } from './models/GetCardBillById'; export type { GetCardProductsBarcodesPdfRequest } from './models/GetCardProductsBarcodesPdfRequest'; export type { GetCardProductsBarcodesPdfResponse } from './models/GetCardProductsBarcodesPdfResponse'; +export type { GetCardSummariesRequest } from './models/GetCardSummariesRequest'; export type { GetChatRequest } from './models/GetChatRequest'; export type { GetChatResponse } from './models/GetChatResponse'; export type { GetClientMarketplacesRequest } from './models/GetClientMarketplacesRequest'; diff --git a/src/client/models/CardSummaryResponse.ts b/src/client/models/CardSummaryResponse.ts index dceb170..a5450a2 100644 --- a/src/client/models/CardSummaryResponse.ts +++ b/src/client/models/CardSummaryResponse.ts @@ -3,7 +3,9 @@ /* tslint:disable */ /* eslint-disable */ import type { CardSummary } from './CardSummary'; +import type { PaginationInfoSchema } from './PaginationInfoSchema'; export type CardSummaryResponse = { summaries: Array; + paginationInfo: PaginationInfoSchema; }; diff --git a/src/client/models/GetCardSummariesRequest.ts b/src/client/models/GetCardSummariesRequest.ts new file mode 100644 index 0000000..2960336 --- /dev/null +++ b/src/client/models/GetCardSummariesRequest.ts @@ -0,0 +1,16 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type GetCardSummariesRequest = { + full: boolean; + cardId?: (number | string | null); + cardName?: (string | null); + marketplaceKey?: (string | null); + shippingWarehouseId?: (number | null); + clientId?: (number | null); + projectId?: (number | null); + boardId?: (number | null); + statusId?: (number | null); +}; + diff --git a/src/client/services/CardService.ts b/src/client/services/CardService.ts index 8d4fa36..56ef855 100644 --- a/src/client/services/CardService.ts +++ b/src/client/services/CardService.ts @@ -56,6 +56,7 @@ import type { CreateCardsFromExcelResponse } from '../models/CreateCardsFromExce import type { GetAvailableEmployeesToAssignResponse } from '../models/GetAvailableEmployeesToAssignResponse'; import type { GetCardProductsBarcodesPdfRequest } from '../models/GetCardProductsBarcodesPdfRequest'; import type { GetCardProductsBarcodesPdfResponse } from '../models/GetCardProductsBarcodesPdfResponse'; +import type { GetCardSummariesRequest } from '../models/GetCardSummariesRequest'; import type { ManageEmployeeRequest } from '../models/ManageEmployeeRequest'; import type { ManageEmployeeResponse } from '../models/ManageEmployeeResponse'; import type { ParseCardsExcelResponse } from '../models/ParseCardsExcelResponse'; @@ -155,16 +156,23 @@ export class CardService { * @throws ApiError */ public static getCardSummaries({ - full, + requestBody, + page, + itemsPerPage, }: { - full: (boolean | null), + requestBody: GetCardSummariesRequest, + page?: (number | null), + itemsPerPage?: (number | null), }): CancelablePromise { return __request(OpenAPI, { - method: 'GET', + method: 'POST', url: '/card/summaries', query: { - 'full': full, + 'page': page, + 'items_per_page': itemsPerPage, }, + body: requestBody, + mediaType: 'application/json', errors: { 422: `Validation Error`, }, diff --git a/src/components/Dnd/Cards/CardAttributesInSummaryItem/CardAttributesInSummaryItem.tsx b/src/components/Dnd/Cards/CardAttributesInSummaryItem/CardAttributesInSummaryItem.tsx index 699cc48..a0ad604 100644 --- a/src/components/Dnd/Cards/CardAttributesInSummaryItem/CardAttributesInSummaryItem.tsx +++ b/src/components/Dnd/Cards/CardAttributesInSummaryItem/CardAttributesInSummaryItem.tsx @@ -56,7 +56,11 @@ const CardAttributesInSummaryItem = ({ cardSummary }: Props) => { .map(cardAttr => { const isHighlight = isHighlightNeeded(cardAttr); return ( - + {cardAttr.attribute.label}: {getAttrValueValue(cardAttr)} ); diff --git a/src/pages/CardsPage/components/CardsPageHeader/CardsPageHeader.tsx b/src/pages/CardsPage/components/CardsPageHeader/CardsPageHeader.tsx index 5f6ef71..635b007 100644 --- a/src/pages/CardsPage/components/CardsPageHeader/CardsPageHeader.tsx +++ b/src/pages/CardsPage/components/CardsPageHeader/CardsPageHeader.tsx @@ -5,7 +5,7 @@ import styles from "../../ui/CardsPage.module.css"; import PageBlock from "../../../../components/PageBlock/PageBlock.tsx"; import DisplayMode from "../../enums/DisplayMode.ts"; import { UseFormReturnType } from "@mantine/form"; -import { CardsPageState } from "../../hooks/useCardsPageState.tsx"; +import { CardsPageState } from "../../hooks/useCardsTableForm.tsx"; import React from "react"; import ObjectSelect from "../../../../components/ObjectSelect/ObjectSelect.tsx"; import CardsTableFiltersModal from "../../modals/CardsTableFiltersModal.tsx"; diff --git a/src/pages/CardsPage/components/CardsTable/CardsTable.tsx b/src/pages/CardsPage/components/CardsTable/CardsTable.tsx index a86f85d..00cdb5f 100644 --- a/src/pages/CardsPage/components/CardsTable/CardsTable.tsx +++ b/src/pages/CardsPage/components/CardsTable/CardsTable.tsx @@ -1,19 +1,27 @@ import { CRUDTableProps } from "../../../../types/CRUDTable.tsx"; import { CardService, CardSummary } from "../../../../client"; -import { FC } from "react"; +import { FC, useEffect, useRef } from "react"; import useCardsTableColumns from "./columns.tsx"; import { BaseTable } from "../../../../components/BaseTable/BaseTable.tsx"; -import { ActionIcon, Flex, Tooltip } from "@mantine/core"; +import { ActionIcon, Flex, Group, Pagination, Stack, Tooltip } from "@mantine/core"; import { IconEdit } from "@tabler/icons-react"; import { MRT_TableOptions } from "mantine-react-table"; import { useCardPageContext } from "../../contexts/CardPageContext.tsx"; +import useCardSummaries from "../../hooks/useCardSummaries.tsx"; +import { CardsPageState } from "../../hooks/useCardsTableForm.tsx"; +import { UseFormReturnType } from "@mantine/form"; +import { useDebouncedValue } from "@mantine/hooks"; type RestProps = { viewOnly?: boolean; + form: UseFormReturnType; }; -type Props = CRUDTableProps & RestProps; +type Props = Omit, "items"> & RestProps; + +const CardsTable: FC = ({ form, onSelectionChange, viewOnly = false }) => { + const [debouncedForm] = useDebouncedValue(form, 300); + const prevDebouncedValues = useRef(debouncedForm?.values); -const CardsTable: FC = ({ items, onSelectionChange, viewOnly = false }) => { const columns = useCardsTableColumns(); const { setSelectedCard } = useCardPageContext(); const onEditClick = (cardSummary: CardSummary) => { @@ -22,35 +30,65 @@ const CardsTable: FC = ({ items, onSelectionChange, viewOnly = false }) = }); }; + const { + summaries, + fetchSummaries, + totalPages, + page, + setPage, + } = useCardSummaries({ + full: true, + values: form?.values, + withPagination: true, + }); + + useEffect(() => { + if (prevDebouncedValues.current !== debouncedForm.values) { + prevDebouncedValues.current = debouncedForm.values; + setPage(1); + } + fetchSummaries(); + }, [debouncedForm.values, page]); + return ( - ( - - - onEditClick(row.original)} - variant={"default"}> - - - - - ), - } as MRT_TableOptions - } - /> + + ( + + + onEditClick(row.original)} + variant={"default"}> + + + + + ), + } as MRT_TableOptions + } + /> + {!viewOnly && ( + + + + )} + ); }; diff --git a/src/pages/CardsPage/contexts/CardPageContext.tsx b/src/pages/CardsPage/contexts/CardPageContext.tsx index f783997..89f1281 100644 --- a/src/pages/CardsPage/contexts/CardPageContext.tsx +++ b/src/pages/CardsPage/contexts/CardPageContext.tsx @@ -4,7 +4,7 @@ import { CardSchema, CardService } from "../../../client"; type CardPageContextState = { selectedCard?: CardSchema; setSelectedCard: (card: CardSchema | undefined) => void; - refetchCards: () => Promise; + refetchCards: () => void; refetchCard: () => void; }; @@ -13,7 +13,7 @@ const CardPageContext = createContext( ); type CardPageContextStateProps = { - refetchCards: () => Promise; + refetchCards: () => void; defaultCardId?: number; } diff --git a/src/pages/CardsPage/contexts/PrefillCardContext.tsx b/src/pages/CardsPage/contexts/PrefillCardContext.tsx index ead247f..7fa9894 100644 --- a/src/pages/CardsPage/contexts/PrefillCardContext.tsx +++ b/src/pages/CardsPage/contexts/PrefillCardContext.tsx @@ -17,12 +17,8 @@ const PrefillCardContext = createContext( undefined ); const usePrefillCardContextState = () => { - const [selectedPrefillCard, setSelectedPrefillCard] = useState( - undefined, - ); - const [prefillCard, setPrefillCard] = useState( - undefined, - ); + const [selectedPrefillCard, setSelectedPrefillCard] = useState(undefined); + const [prefillCard, setPrefillCard] = useState(undefined); const [prefillOpened, { open, close }] = useDisclosure(false); const prefillOnClose = close; const prefillOnOpen = open; diff --git a/src/pages/CardsPage/drawers/CardPrefillDrawer/CardPrefillDrawer.tsx b/src/pages/CardsPage/drawers/CardPrefillDrawer/CardPrefillDrawer.tsx index 90936c4..c0dfdcf 100644 --- a/src/pages/CardsPage/drawers/CardPrefillDrawer/CardPrefillDrawer.tsx +++ b/src/pages/CardsPage/drawers/CardPrefillDrawer/CardPrefillDrawer.tsx @@ -1,20 +1,10 @@ -import { FC, useEffect } from "react"; -import { Button, Drawer, Flex, rem, TextInput } from "@mantine/core"; -import CardsTable from "./components/tables/CardsTable/CardsTable.tsx"; -import Preview from "./components/Preview/Preview.tsx"; -import styles from "./CardPrefillDrawer.module.css"; -import BaseMarketplaceSelect from "../../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx"; -import usePrefillCard from "./hooks/usePrefillCard.tsx"; -import { notifications } from "../../../../shared/lib/notifications.ts"; +import { FC } from "react"; +import { Drawer, rem } from "@mantine/core"; import { usePrefillCardContext } from "../../contexts/PrefillCardContext.tsx"; +import CardPrefillDrawerContent from "./components/CardPrefillDrawerContent/CardPrefillDrawerContent.tsx"; const CardPrefillDrawer: FC = () => { - const { prefillOpened, prefillOnClose, selectedPrefillCard, setPrefillCard, prefillCard } = usePrefillCardContext(); - const { data, form } = usePrefillCard(); - - useEffect(() => { - if (prefillOpened) return; - }, [prefillOpened]); + const { prefillOpened, prefillOnClose } = usePrefillCardContext(); return ( { }, }} > -
-
-
- - - form.setFieldValue("marketplace", null) - } - clearable - placeholder={"Выберите маркетплейс"} - {...form.getInputProps("marketplace")} - /> -
- - - - { - prefillCard && - - } - -
-
- +
); }; diff --git a/src/pages/CardsPage/drawers/CardPrefillDrawer/components/CardPrefillDrawerContent/CardPrefillDrawerContent.tsx b/src/pages/CardsPage/drawers/CardPrefillDrawer/components/CardPrefillDrawerContent/CardPrefillDrawerContent.tsx new file mode 100644 index 0000000..e0eaff4 --- /dev/null +++ b/src/pages/CardsPage/drawers/CardPrefillDrawer/components/CardPrefillDrawerContent/CardPrefillDrawerContent.tsx @@ -0,0 +1,78 @@ +import styles from "../../CardPrefillDrawer.module.css"; +import { Button, Flex, TextInput } from "@mantine/core"; +import BaseMarketplaceSelect + from "../../../../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx"; +import CardsTable from "../tables/CardsTable/CardsTable.tsx"; +import { notifications } from "../../../../../../shared/lib/notifications.ts"; +import Preview from "../Preview/Preview.tsx"; +import usePrefillCard from "../../hooks/usePrefillCard.tsx"; +import { usePrefillCardContext } from "../../../../contexts/PrefillCardContext.tsx"; + + +const CardPrefillDrawerContent = () => { + const { prefillOnClose, selectedPrefillCard, setPrefillCard, prefillCard } = usePrefillCardContext(); + const { + summaries, + idOrName, + setIdOrName, + marketplace, + setMarketplace, + totalPages, + page, + setPage, + } = usePrefillCard(); + + return ( + <> +
+
+
+ setIdOrName(e.target.value)} + /> + setMarketplace(null)} + clearable + placeholder={"Выберите маркетплейс"} + value={marketplace || undefined} + onChange={setMarketplace} + /> +
+ + + + { + prefillCard && + + } + +
+
+ + + ); +}; + +export default CardPrefillDrawerContent; diff --git a/src/pages/CardsPage/drawers/CardPrefillDrawer/components/tables/CardsTable/CardsTable.tsx b/src/pages/CardsPage/drawers/CardPrefillDrawer/components/tables/CardsTable/CardsTable.tsx index 16a84aa..d2dabc8 100644 --- a/src/pages/CardsPage/drawers/CardPrefillDrawer/components/tables/CardsTable/CardsTable.tsx +++ b/src/pages/CardsPage/drawers/CardPrefillDrawer/components/tables/CardsTable/CardsTable.tsx @@ -1,47 +1,62 @@ -import { FC, useEffect } from "react"; +import { FC, useEffect, useState } from "react"; import useCardsTableColumns from "./columns.tsx"; import { CardSummary } from "../../../../../../../client"; import { BaseTable } from "../../../../../../../components/BaseTable/BaseTable.tsx"; import { usePrefillCardContext } from "../../../../../contexts/PrefillCardContext.tsx"; +import { Group, Pagination, Stack } from "@mantine/core"; type Props = { items: CardSummary[]; + totalPages: number; + page: number; + setPage: (page: number) => void; }; -const CardsTable: FC = ({ items }) => { +const CardsTable: FC = ({ items, totalPages, page, setPage }) => { const { selectPrefillCard } = usePrefillCardContext(); const columns = useCardsTableColumns(); const defaultSorting = [{ id: "createdAt", desc: false }]; + const [isInitial, setIsInitial] = useState(true); useEffect(() => { - if (items.length < 1) return; - selectPrefillCard(items[0].id); - }, []); + if (isInitial && items.length > 0) { + selectPrefillCard(items[0].id); + setIsInitial(false); + } + }, [items]); return ( - + + /> + + + + ); }; diff --git a/src/pages/CardsPage/drawers/CardPrefillDrawer/hooks/usePrefillCard.tsx b/src/pages/CardsPage/drawers/CardPrefillDrawer/hooks/usePrefillCard.tsx index 0f5c12d..8e791af 100644 --- a/src/pages/CardsPage/drawers/CardPrefillDrawer/hooks/usePrefillCard.tsx +++ b/src/pages/CardsPage/drawers/CardPrefillDrawer/hooks/usePrefillCard.tsx @@ -1,56 +1,58 @@ -import { useForm } from "@mantine/form"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { BaseMarketplaceSchema } from "../../../../../client"; -import { useCardSummariesFull } from "../../../hooks/useCardSummaries.tsx"; -import isModuleInProject from "../../../../../modules/utils/isModuleInProject.ts"; -import { ModuleNames } from "../../../../../modules/modules.tsx"; +import useCardSummaries from "../../../hooks/useCardSummaries.tsx"; +import { useDebouncedValue } from "@mantine/hooks"; -type State = { - idOrName: string | null; - marketplace: BaseMarketplaceSchema | null; -}; const usePrefillCard = () => { - const { objects } = useCardSummariesFull(); - const form = useForm({ - initialValues: { - idOrName: null, - marketplace: null, - }, - }); - const [data, setData] = useState(objects); + const [idOrName, setIdOrName] = useState(""); + const [debouncedIdOrName] = useDebouncedValue(idOrName, 500); + const prevIdOrName = useRef(idOrName); + const [marketplace, setMarketplace] = useState(null); + const prevMarketplace = useRef(marketplace); - const applyFilters = () => { - let result = objects; + const getValues = () => { + let id: number | null = parseInt(debouncedIdOrName || ""); + if (isNaN(id)) id = null; - result = result.filter(obj => isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, obj.board.project)); - - if (form.values.idOrName) { - if (isNaN(parseInt(form.values.idOrName))) { - const name: string = form.values.idOrName.toLowerCase(); - result = result.filter( - obj => obj.name.toLowerCase().search(name) !== -1, - ); - } else { - const id = parseInt(form.values.idOrName); - result = result.filter( - obj => obj.id === id, - ); - } - } - if (form.values.marketplace) { - result = result.filter( - obj => obj.baseMarketplace?.key === form.values.marketplace?.key, - ); - } - setData(result); + return { + cardId: id, + cardName: id ? null : debouncedIdOrName, + marketplace, + }; }; - useEffect(() => { - applyFilters(); - }, [form.values, objects]); + const { + summaries, + fetchSummaries, + totalPages, + page, + setPage, + } = useCardSummaries({ + full: true, + values: getValues(), + withPagination: true, + }); - return { data, form }; + useEffect(() => { + if (prevIdOrName.current !== debouncedIdOrName || prevMarketplace.current !== marketplace) { + prevIdOrName.current = debouncedIdOrName; + prevMarketplace.current = marketplace; + setPage(1); + } + fetchSummaries(); + }, [debouncedIdOrName, marketplace, page]); + + return { + summaries, + idOrName, + setIdOrName, + marketplace, + setMarketplace, + totalPages, + page, + setPage, + }; }; export default usePrefillCard; diff --git a/src/pages/CardsPage/hooks/useCardSummaries.tsx b/src/pages/CardsPage/hooks/useCardSummaries.tsx index 8f486b6..917cc2a 100644 --- a/src/pages/CardsPage/hooks/useCardSummaries.tsx +++ b/src/pages/CardsPage/hooks/useCardSummaries.tsx @@ -1,22 +1,50 @@ -import { useQuery } from "@tanstack/react-query"; -import { CardService } from "../../../client"; -import ObjectList from "../../../hooks/objectList.tsx"; +import { useState } from "react"; +import { CardService, CardSummary } from "../../../client"; +import { CardsPageState } from "./useCardsTableForm.tsx"; -export const useCardSummaries = () => { - const { data: summariesRaw = [], refetch } = useQuery({ - queryKey: ["getCardSummaries"], - queryFn: () => CardService.getCardSummaries({ full: false }), - select: data => data.summaries || [], // Трансформируем полученные данные - }); - // Теперь summaries будет содержать либо трансформированные данные, либо пустой массив по умолчанию - // isLoading и isError могут быть использованы для отображения индикаторов загрузки или ошибки +type Props = { + full: boolean; + values?: CardsPageState; + withPagination?: boolean; + itemsPerPage?: number; +} - return { summariesRaw, refetch }; +const useCardSummaries = ({ full, values, withPagination = false, itemsPerPage = 10 }: Props) => { + const [summaries, setSummaries] = useState([]); + const [page, setPage] = useState(1); + const [totalPages, setTotalPages] = useState(0); + + const fetchSummaries = () => { + CardService.getCardSummaries({ + page: withPagination ? page : null, + itemsPerPage: withPagination ? itemsPerPage : null, + requestBody: { + full, + cardId: values?.cardId, + cardName: values?.cardName, + marketplaceKey: values?.marketplace?.key, + shippingWarehouseId: values?.shippingWarehouse?.id, + clientId: values?.client?.id, + projectId: values?.project?.id, + boardId: values?.board?.id, + statusId: values?.status?.id, + }, + }) + .then(({ summaries, paginationInfo }) => { + setSummaries(summaries); + setTotalPages(paginationInfo.totalPages); + }) + .catch(err => console.log(err)); + }; + + return { + summaries, + fetchSummaries, + page, + setPage, + totalPages, + }; }; -export const useCardSummariesFull = () => - ObjectList({ - queryFn: () => CardService.getCardSummaries({ full: true }), - queryKey: "getCardSummariesFull", - getObjectsFn: response => response.summaries, - }); + +export default useCardSummaries; diff --git a/src/pages/CardsPage/hooks/useCardsPageState.tsx b/src/pages/CardsPage/hooks/useCardsPageState.tsx deleted file mode 100644 index bc73aea..0000000 --- a/src/pages/CardsPage/hooks/useCardsPageState.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { useCardSummariesFull } from "./useCardSummaries.tsx"; -import { useForm } from "@mantine/form"; -import { useEffect, useState } from "react"; -import { BaseMarketplaceSchema, BoardSchema, ClientSchema, ProjectSchema, StatusSchema } from "../../../client"; - -export type CardsPageState = { - id: number | null; - marketplace: BaseMarketplaceSchema | null; - client: ClientSchema | null; - - projectForTable: ProjectSchema | null; - board: BoardSchema | null; - status: StatusSchema | null; -}; - -const useCardsPageState = () => { - const { objects } = useCardSummariesFull(); - - const form = useForm({ - initialValues: { - id: null, - marketplace: null, - client: null, - - projectForTable: null, - board: null, - status: null, - }, - }); - - const [data, setData] = useState(objects); - - const applyFilters = () => { - let result = objects; - if (form.values.id) { - result = result.filter( - obj => obj.id === form.values.id, - ); - } - if (form.values.marketplace) { - result = result.filter( - obj => obj.baseMarketplace?.key === form.values.marketplace?.key, - ); - } - if (form.values.projectForTable) { - result = result.filter( - obj => obj.board.projectId === form.values.projectForTable?.id, - ); - - if (form.values.board) { - result = result.filter( - obj => obj.board.id === form.values.board?.id, - ); - - if (form.values.status) { - result = result.filter( - obj => obj.status.id === form.values.status?.id, - ); - } - } - } - if (form.values.client) { - result = result.filter( - obj => obj.clientName === form.values.client?.name, - ); - } - setData(result); - }; - - useEffect(() => { - applyFilters(); - }, [form.values, objects]); - - return { data, form }; -}; - -export default useCardsPageState; diff --git a/src/pages/CardsPage/hooks/useCardsTableForm.tsx b/src/pages/CardsPage/hooks/useCardsTableForm.tsx new file mode 100644 index 0000000..aa66bee --- /dev/null +++ b/src/pages/CardsPage/hooks/useCardsTableForm.tsx @@ -0,0 +1,39 @@ +import { useForm } from "@mantine/form"; +import { + BaseMarketplaceSchema, + BoardSchema, + ClientSchema, + ProjectSchema, + ShippingWarehouseSchema, + StatusSchema, +} from "../../../client"; + +export type CardsPageState = { + cardId?: number | null; + cardName?: string | null; + marketplace?: BaseMarketplaceSchema | null; + shippingWarehouse?: ShippingWarehouseSchema | null; + client?: ClientSchema | null; + + project?: ProjectSchema | null; + board?: BoardSchema | null; + status?: StatusSchema | null; +}; + +const useCardsTableForm = () => { + const form = useForm({ + initialValues: { + cardId: null, + marketplace: null, + client: null, + + project: null, + board: null, + status: null, + }, + }); + + return { form }; +}; + +export default useCardsTableForm; diff --git a/src/pages/CardsPage/modals/CardsTableFiltersModal.tsx b/src/pages/CardsPage/modals/CardsTableFiltersModal.tsx index 1ffb859..3062ebb 100644 --- a/src/pages/CardsPage/modals/CardsTableFiltersModal.tsx +++ b/src/pages/CardsPage/modals/CardsTableFiltersModal.tsx @@ -1,7 +1,7 @@ import { ProjectSchema } from "../../../client"; import { Flex, Modal, NumberInput, rem } from "@mantine/core"; import { UseFormReturnType } from "@mantine/form"; -import { CardsPageState } from "../hooks/useCardsPageState.tsx"; +import { CardsPageState } from "../hooks/useCardsTableForm.tsx"; import ObjectSelect from "../../../components/ObjectSelect/ObjectSelect.tsx"; import CardStatusSelect from "../../../components/CardStatusSelect/CardStatusSelect.tsx"; import BaseMarketplaceSelect from "../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx"; @@ -33,7 +33,7 @@ const CardsTableFiltersModal = ({ form, projects }: Props) => { { data={projects} clearable searchable - {...form.getInputProps("projectForTable")} - onClear={() => form.setFieldValue("projectForTable", null)} + {...form.getInputProps("project")} + onClear={() => form.setFieldValue("project", null)} /> diff --git a/src/pages/CardsPage/ui/CardsPage.tsx b/src/pages/CardsPage/ui/CardsPage.tsx index 4bab51d..1b3ba0e 100644 --- a/src/pages/CardsPage/ui/CardsPage.tsx +++ b/src/pages/CardsPage/ui/CardsPage.tsx @@ -1,10 +1,9 @@ -import { FC, useMemo, useState } from "react"; -import { useCardSummaries } from "../hooks/useCardSummaries.tsx"; +import { FC, useEffect, useMemo, useState } from "react"; import PageBlock from "../../../components/PageBlock/PageBlock.tsx"; import CardEditDrawer from "../drawers/CardEditDrawer/CardEditDrawer.tsx"; import { CardPageContextProvider } from "../contexts/CardPageContext.tsx"; import { rem } from "@mantine/core"; -import useCardsPageState from "../hooks/useCardsPageState.tsx"; +import useCardsTableForm from "../hooks/useCardsTableForm.tsx"; import CardsTable from "../components/CardsTable/CardsTable.tsx"; import { motion } from "framer-motion"; import CardPrefillDrawer from "../drawers/CardPrefillDrawer/CardPrefillDrawer.tsx"; @@ -17,30 +16,35 @@ import { ProjectsEditorContextProvider } from "../contexts/ProjectsEditorContext import ProjectEditDrawer from "../drawers/ProjectEditDrawer/ProjectEditDrawer.tsx"; import Boards from "../../../components/Dnd/Boards/Boards/Boards.tsx"; import { DndContextProvider } from "../contexts/DndContext.tsx"; +import useCardSummaries from "../hooks/useCardSummaries.tsx"; export const CardsPage: FC = () => { - const { data, form } = useCardsPageState(); + const { form } = useCardsTableForm(); const { dealId } = useParams({ strict: false }); - const { summariesRaw, refetch: refetchSummaries } = useCardSummaries(); + const { summaries, fetchSummaries } = useCardSummaries({ full: false }); const [displayMode, setDisplayMode] = useState(DisplayMode.BOARD); + useEffect(() => { + fetchSummaries(); + }, []); + const tableBody = useMemo(() => { return ( - + ); - }, [data]); + }, [form]); const boardsBody = useMemo(() => { return ( ); - }, [summariesRaw]); + }, [summaries]); const getBody = () => { return ( @@ -72,9 +76,7 @@ export const CardsPage: FC = () => { { - await refetchSummaries(); - }} + refetchCards={fetchSummaries} > diff --git a/src/pages/ShippingWarehousesPage/components/CardsTablePreview/CardsTablePreview.tsx b/src/pages/ShippingWarehousesPage/components/CardsTablePreview/CardsTablePreview.tsx new file mode 100644 index 0000000..ce9163f --- /dev/null +++ b/src/pages/ShippingWarehousesPage/components/CardsTablePreview/CardsTablePreview.tsx @@ -0,0 +1,47 @@ +import { CRUDTableProps } from "../../../../types/CRUDTable.tsx"; +import { CardSummary, ShippingWarehouseSchema } from "../../../../client"; +import { FC, useEffect } from "react"; +import { BaseTable } from "../../../../components/BaseTable/BaseTable.tsx"; +import { MRT_TableOptions } from "mantine-react-table"; +import useCardsTablePreviewColumns from "./columns.tsx"; +import useCardSummaries from "../../../CardsPage/hooks/useCardSummaries.tsx"; + +type RestProps = { + viewOnly?: boolean; + shippingWarehouse: ShippingWarehouseSchema; +}; +type Props = Omit, "items"> & RestProps; + +const CardsTablePreview: FC = ({ shippingWarehouse, onSelectionChange }) => { + const columns = useCardsTablePreviewColumns(); + + const { summaries, fetchSummaries } = useCardSummaries({ + full: true, + values: { + shippingWarehouse, + }, + withPagination: true, + itemsPerPage: 5, + }); + + useEffect(() => { + fetchSummaries(); + }, []); + + return ( + + } + /> + ); +}; + +export default CardsTablePreview; diff --git a/src/pages/ShippingWarehousesPage/components/CardsTablePreview/columns.tsx b/src/pages/ShippingWarehousesPage/components/CardsTablePreview/columns.tsx new file mode 100644 index 0000000..1a682c3 --- /dev/null +++ b/src/pages/ShippingWarehousesPage/components/CardsTablePreview/columns.tsx @@ -0,0 +1,56 @@ +import { useMemo } from "react"; +import { MRT_ColumnDef } from "mantine-react-table"; +import { CardSummary } from "../../../../client"; +import { ActionIcon, Image } from "@mantine/core"; + +const useCardsTablePreviewColumns = () => { + return useMemo[]>( + () => [ + { + accessorKey: "id", + header: "Номер", + size: 20, + }, + { + header: "Маркетплейс", + size: 10, + Cell: ({ row }) => ( + + + + ), + }, + { + header: "Дата создания", + accessorKey: "createdAt", + Cell: ({ row }) => + new Date(row.original.createdAt).toLocaleString("ru-RU"), + enableSorting: true, + sortingFn: (rowA, rowB) => + new Date(rowB.original.createdAt).getTime() - + new Date(rowA.original.createdAt).getTime(), + }, + { + accessorKey: "name", + header: "Название", + enableSorting: false, + }, + { + accessorKey: "clientName", + header: "Клиент", + enableSorting: false, + }, + { + header: "Общая стоимость", + Cell: ({ row }) => + row.original.totalPrice.toLocaleString("ru-RU") + "₽", + accessorKey: "totalPrice", + }, + ], + [], + ); +}; + +export default useCardsTablePreviewColumns; diff --git a/src/pages/ShippingWarehousesPage/modals/ShippingWarehouseForm.tsx b/src/pages/ShippingWarehousesPage/modals/ShippingWarehouseForm.tsx index a8b9c8b..9e0e3b6 100644 --- a/src/pages/ShippingWarehousesPage/modals/ShippingWarehouseForm.tsx +++ b/src/pages/ShippingWarehousesPage/modals/ShippingWarehouseForm.tsx @@ -3,9 +3,7 @@ import { CardSummary, ShippingWarehouseSchema } from "../../../client"; import { ContextModalProps } from "@mantine/modals"; import { useForm } from "@mantine/form"; import { Input, TextInput } from "@mantine/core"; -import CardsTable from "../../CardsPage/components/CardsTable/CardsTable.tsx"; -import { CardPageContextProvider } from "../../CardsPage/contexts/CardPageContext.tsx"; -import CardEditDrawer from "../../CardsPage/drawers/CardEditDrawer/CardEditDrawer.tsx"; +import CardsTablePreview from "../components/CardsTablePreview/CardsTablePreview.tsx"; type RestProps = { summaries: CardSummary[]; @@ -27,34 +25,28 @@ const ShippingWarehouseForm = ({ }, }); return ( - {}}> - context.closeContextModal(id)}> - - <> - - {isEditing && ( - - - - )} - - - - - + context.closeContextModal(id)}> + + <> + + {isEditing && ( + + + + )} + + + ); }; diff --git a/src/pages/ShippingWarehousesPage/ui/ShippingWarehousesPage.tsx b/src/pages/ShippingWarehousesPage/ui/ShippingWarehousesPage.tsx index 91a79b3..e647296 100644 --- a/src/pages/ShippingWarehousesPage/ui/ShippingWarehousesPage.tsx +++ b/src/pages/ShippingWarehousesPage/ui/ShippingWarehousesPage.tsx @@ -1,20 +1,23 @@ import styles from "../../ServicesPage/ui/ServicesPage.module.css"; import PageBlock from "../../../components/PageBlock/PageBlock.tsx"; import ShippingWarehousesTable from "../components/ShippingWarehousesTable/ShippingWarehousesTable.tsx"; -import useShippingWarehousesList from "../../../components/Selects/ShippingWarehouseAutocomplete/hooks/useShippingWarehousesList.tsx"; +import useShippingWarehousesList + from "../../../components/Selects/ShippingWarehouseAutocomplete/hooks/useShippingWarehousesList.tsx"; import { Button } from "@mantine/core"; import { modals } from "@mantine/modals"; import { useCRUD } from "../../../hooks/useCRUD.tsx"; -import { - ShippingWarehouseSchema, - ShippingWarehouseService, -} from "../../../client"; +import { ShippingWarehouseSchema, ShippingWarehouseService } from "../../../client"; import { notifications } from "../../../shared/lib/notifications.ts"; -import { useCardSummariesFull } from "../../CardsPage/hooks/useCardSummaries.tsx"; +import useCardSummaries from "../../CardsPage/hooks/useCardSummaries.tsx"; export const ShippingWarehousesPage = () => { const { shippingWarehouses, refetch } = useShippingWarehousesList(); - const { objects: summaries } = useCardSummariesFull(); + const { summaries } = useCardSummaries({ + full: true, + withPagination: true, + values: {}, + }); + const crud = useCRUD({ onChange: element => { ShippingWarehouseService.updateShippingWarehouse({