fix: cards fetch optimization
This commit is contained in:
@@ -252,6 +252,7 @@ export type { GetBoardsResponse } from './models/GetBoardsResponse';
|
|||||||
export type { GetCardBillById } from './models/GetCardBillById';
|
export type { GetCardBillById } from './models/GetCardBillById';
|
||||||
export type { GetCardProductsBarcodesPdfRequest } from './models/GetCardProductsBarcodesPdfRequest';
|
export type { GetCardProductsBarcodesPdfRequest } from './models/GetCardProductsBarcodesPdfRequest';
|
||||||
export type { GetCardProductsBarcodesPdfResponse } from './models/GetCardProductsBarcodesPdfResponse';
|
export type { GetCardProductsBarcodesPdfResponse } from './models/GetCardProductsBarcodesPdfResponse';
|
||||||
|
export type { GetCardSummariesRequest } from './models/GetCardSummariesRequest';
|
||||||
export type { GetChatRequest } from './models/GetChatRequest';
|
export type { GetChatRequest } from './models/GetChatRequest';
|
||||||
export type { GetChatResponse } from './models/GetChatResponse';
|
export type { GetChatResponse } from './models/GetChatResponse';
|
||||||
export type { GetClientMarketplacesRequest } from './models/GetClientMarketplacesRequest';
|
export type { GetClientMarketplacesRequest } from './models/GetClientMarketplacesRequest';
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import type { CardSummary } from './CardSummary';
|
import type { CardSummary } from './CardSummary';
|
||||||
|
import type { PaginationInfoSchema } from './PaginationInfoSchema';
|
||||||
export type CardSummaryResponse = {
|
export type CardSummaryResponse = {
|
||||||
summaries: Array<CardSummary>;
|
summaries: Array<CardSummary>;
|
||||||
|
paginationInfo: PaginationInfoSchema;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
16
src/client/models/GetCardSummariesRequest.ts
Normal file
16
src/client/models/GetCardSummariesRequest.ts
Normal file
@@ -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);
|
||||||
|
};
|
||||||
|
|
||||||
@@ -56,6 +56,7 @@ import type { CreateCardsFromExcelResponse } from '../models/CreateCardsFromExce
|
|||||||
import type { GetAvailableEmployeesToAssignResponse } from '../models/GetAvailableEmployeesToAssignResponse';
|
import type { GetAvailableEmployeesToAssignResponse } from '../models/GetAvailableEmployeesToAssignResponse';
|
||||||
import type { GetCardProductsBarcodesPdfRequest } from '../models/GetCardProductsBarcodesPdfRequest';
|
import type { GetCardProductsBarcodesPdfRequest } from '../models/GetCardProductsBarcodesPdfRequest';
|
||||||
import type { GetCardProductsBarcodesPdfResponse } from '../models/GetCardProductsBarcodesPdfResponse';
|
import type { GetCardProductsBarcodesPdfResponse } from '../models/GetCardProductsBarcodesPdfResponse';
|
||||||
|
import type { GetCardSummariesRequest } from '../models/GetCardSummariesRequest';
|
||||||
import type { ManageEmployeeRequest } from '../models/ManageEmployeeRequest';
|
import type { ManageEmployeeRequest } from '../models/ManageEmployeeRequest';
|
||||||
import type { ManageEmployeeResponse } from '../models/ManageEmployeeResponse';
|
import type { ManageEmployeeResponse } from '../models/ManageEmployeeResponse';
|
||||||
import type { ParseCardsExcelResponse } from '../models/ParseCardsExcelResponse';
|
import type { ParseCardsExcelResponse } from '../models/ParseCardsExcelResponse';
|
||||||
@@ -155,16 +156,23 @@ export class CardService {
|
|||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public static getCardSummaries({
|
public static getCardSummaries({
|
||||||
full,
|
requestBody,
|
||||||
|
page,
|
||||||
|
itemsPerPage,
|
||||||
}: {
|
}: {
|
||||||
full: (boolean | null),
|
requestBody: GetCardSummariesRequest,
|
||||||
|
page?: (number | null),
|
||||||
|
itemsPerPage?: (number | null),
|
||||||
}): CancelablePromise<CardSummaryResponse> {
|
}): CancelablePromise<CardSummaryResponse> {
|
||||||
return __request(OpenAPI, {
|
return __request(OpenAPI, {
|
||||||
method: 'GET',
|
method: 'POST',
|
||||||
url: '/card/summaries',
|
url: '/card/summaries',
|
||||||
query: {
|
query: {
|
||||||
'full': full,
|
'page': page,
|
||||||
|
'items_per_page': itemsPerPage,
|
||||||
},
|
},
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
errors: {
|
errors: {
|
||||||
422: `Validation Error`,
|
422: `Validation Error`,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -56,7 +56,11 @@ const CardAttributesInSummaryItem = ({ cardSummary }: Props) => {
|
|||||||
.map(cardAttr => {
|
.map(cardAttr => {
|
||||||
const isHighlight = isHighlightNeeded(cardAttr);
|
const isHighlight = isHighlightNeeded(cardAttr);
|
||||||
return (
|
return (
|
||||||
<Text c={isHighlight ? "red" : "gray.6"} size={"sm"}>
|
<Text
|
||||||
|
key={cardAttr.attribute.id}
|
||||||
|
c={isHighlight ? "red" : "gray.6"}
|
||||||
|
size={"sm"}
|
||||||
|
>
|
||||||
{cardAttr.attribute.label}: {getAttrValueValue(cardAttr)}
|
{cardAttr.attribute.label}: {getAttrValueValue(cardAttr)}
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import styles from "../../ui/CardsPage.module.css";
|
|||||||
import PageBlock from "../../../../components/PageBlock/PageBlock.tsx";
|
import PageBlock from "../../../../components/PageBlock/PageBlock.tsx";
|
||||||
import DisplayMode from "../../enums/DisplayMode.ts";
|
import DisplayMode from "../../enums/DisplayMode.ts";
|
||||||
import { UseFormReturnType } from "@mantine/form";
|
import { UseFormReturnType } from "@mantine/form";
|
||||||
import { CardsPageState } from "../../hooks/useCardsPageState.tsx";
|
import { CardsPageState } from "../../hooks/useCardsTableForm.tsx";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ObjectSelect from "../../../../components/ObjectSelect/ObjectSelect.tsx";
|
import ObjectSelect from "../../../../components/ObjectSelect/ObjectSelect.tsx";
|
||||||
import CardsTableFiltersModal from "../../modals/CardsTableFiltersModal.tsx";
|
import CardsTableFiltersModal from "../../modals/CardsTableFiltersModal.tsx";
|
||||||
|
|||||||
@@ -1,19 +1,27 @@
|
|||||||
import { CRUDTableProps } from "../../../../types/CRUDTable.tsx";
|
import { CRUDTableProps } from "../../../../types/CRUDTable.tsx";
|
||||||
import { CardService, CardSummary } from "../../../../client";
|
import { CardService, CardSummary } from "../../../../client";
|
||||||
import { FC } from "react";
|
import { FC, useEffect, useRef } from "react";
|
||||||
import useCardsTableColumns from "./columns.tsx";
|
import useCardsTableColumns from "./columns.tsx";
|
||||||
import { BaseTable } from "../../../../components/BaseTable/BaseTable.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 { IconEdit } from "@tabler/icons-react";
|
||||||
import { MRT_TableOptions } from "mantine-react-table";
|
import { MRT_TableOptions } from "mantine-react-table";
|
||||||
import { useCardPageContext } from "../../contexts/CardPageContext.tsx";
|
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 = {
|
type RestProps = {
|
||||||
viewOnly?: boolean;
|
viewOnly?: boolean;
|
||||||
|
form: UseFormReturnType<CardsPageState>;
|
||||||
};
|
};
|
||||||
type Props = CRUDTableProps<CardSummary> & RestProps;
|
type Props = Omit<CRUDTableProps<CardSummary>, "items"> & RestProps;
|
||||||
|
|
||||||
|
const CardsTable: FC<Props> = ({ form, onSelectionChange, viewOnly = false }) => {
|
||||||
|
const [debouncedForm] = useDebouncedValue(form, 300);
|
||||||
|
const prevDebouncedValues = useRef(debouncedForm?.values);
|
||||||
|
|
||||||
const CardsTable: FC<Props> = ({ items, onSelectionChange, viewOnly = false }) => {
|
|
||||||
const columns = useCardsTableColumns();
|
const columns = useCardsTableColumns();
|
||||||
const { setSelectedCard } = useCardPageContext();
|
const { setSelectedCard } = useCardPageContext();
|
||||||
const onEditClick = (cardSummary: CardSummary) => {
|
const onEditClick = (cardSummary: CardSummary) => {
|
||||||
@@ -22,35 +30,65 @@ const CardsTable: FC<Props> = ({ 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 (
|
return (
|
||||||
<BaseTable
|
<Stack>
|
||||||
data={items}
|
<BaseTable
|
||||||
columns={columns}
|
data={summaries}
|
||||||
onSelectionChange={onSelectionChange}
|
columns={columns}
|
||||||
restProps={
|
onSelectionChange={onSelectionChange}
|
||||||
{
|
restProps={
|
||||||
enableSorting: true,
|
{
|
||||||
enableColumnActions: false,
|
enableSorting: true,
|
||||||
enablePagination: !viewOnly,
|
enableColumnActions: false,
|
||||||
enableBottomToolbar: !viewOnly,
|
paginationDisplayMode: "pages",
|
||||||
paginationDisplayMode: "pages",
|
enableRowActions: true,
|
||||||
enableRowActions: true,
|
enableRowSelection: true,
|
||||||
enableRowSelection: true,
|
renderRowActions: ({ row }) => (
|
||||||
renderRowActions: ({ row }) => (
|
<Flex gap="md">
|
||||||
<Flex gap="md">
|
<Tooltip label="Редактировать">
|
||||||
<Tooltip label="Редактировать">
|
<ActionIcon
|
||||||
<ActionIcon
|
disabled={viewOnly}
|
||||||
disabled={viewOnly}
|
onClick={() => onEditClick(row.original)}
|
||||||
onClick={() => onEditClick(row.original)}
|
variant={"default"}>
|
||||||
variant={"default"}>
|
<IconEdit />
|
||||||
<IconEdit />
|
</ActionIcon>
|
||||||
</ActionIcon>
|
</Tooltip>
|
||||||
</Tooltip>
|
</Flex>
|
||||||
</Flex>
|
),
|
||||||
),
|
} as MRT_TableOptions<CardSummary>
|
||||||
} as MRT_TableOptions<CardSummary>
|
}
|
||||||
}
|
/>
|
||||||
/>
|
{!viewOnly && (
|
||||||
|
<Group justify={"flex-end"}>
|
||||||
|
<Pagination
|
||||||
|
withEdges
|
||||||
|
total={totalPages}
|
||||||
|
value={page}
|
||||||
|
onChange={setPage}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { CardSchema, CardService } from "../../../client";
|
|||||||
type CardPageContextState = {
|
type CardPageContextState = {
|
||||||
selectedCard?: CardSchema;
|
selectedCard?: CardSchema;
|
||||||
setSelectedCard: (card: CardSchema | undefined) => void;
|
setSelectedCard: (card: CardSchema | undefined) => void;
|
||||||
refetchCards: () => Promise<void>;
|
refetchCards: () => void;
|
||||||
refetchCard: () => void;
|
refetchCard: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ const CardPageContext = createContext<CardPageContextState | undefined>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
type CardPageContextStateProps = {
|
type CardPageContextStateProps = {
|
||||||
refetchCards: () => Promise<void>;
|
refetchCards: () => void;
|
||||||
defaultCardId?: number;
|
defaultCardId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,8 @@ const PrefillCardContext = createContext<PrefillCardContextState | undefined>(
|
|||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
const usePrefillCardContextState = () => {
|
const usePrefillCardContextState = () => {
|
||||||
const [selectedPrefillCard, setSelectedPrefillCard] = useState<CardSchema | undefined>(
|
const [selectedPrefillCard, setSelectedPrefillCard] = useState<CardSchema | undefined>(undefined);
|
||||||
undefined,
|
const [prefillCard, setPrefillCard] = useState<CardSchema | undefined>(undefined);
|
||||||
);
|
|
||||||
const [prefillCard, setPrefillCard] = useState<CardSchema | undefined>(
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
const [prefillOpened, { open, close }] = useDisclosure(false);
|
const [prefillOpened, { open, close }] = useDisclosure(false);
|
||||||
const prefillOnClose = close;
|
const prefillOnClose = close;
|
||||||
const prefillOnOpen = open;
|
const prefillOnOpen = open;
|
||||||
|
|||||||
@@ -1,20 +1,10 @@
|
|||||||
import { FC, useEffect } from "react";
|
import { FC } from "react";
|
||||||
import { Button, Drawer, Flex, rem, TextInput } from "@mantine/core";
|
import { Drawer, rem } 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 { usePrefillCardContext } from "../../contexts/PrefillCardContext.tsx";
|
import { usePrefillCardContext } from "../../contexts/PrefillCardContext.tsx";
|
||||||
|
import CardPrefillDrawerContent from "./components/CardPrefillDrawerContent/CardPrefillDrawerContent.tsx";
|
||||||
|
|
||||||
const CardPrefillDrawer: FC = () => {
|
const CardPrefillDrawer: FC = () => {
|
||||||
const { prefillOpened, prefillOnClose, selectedPrefillCard, setPrefillCard, prefillCard } = usePrefillCardContext();
|
const { prefillOpened, prefillOnClose } = usePrefillCardContext();
|
||||||
const { data, form } = usePrefillCard();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (prefillOpened) return;
|
|
||||||
}, [prefillOpened]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
@@ -33,48 +23,7 @@ const CardPrefillDrawer: FC = () => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={styles["card-container"]}>
|
<CardPrefillDrawerContent />
|
||||||
<div className={styles["card-container-wrapper"]}>
|
|
||||||
<div className={styles["top-panel"]}>
|
|
||||||
<TextInput
|
|
||||||
placeholder={"Введите название / id"}
|
|
||||||
{...form.getInputProps("idOrName")}
|
|
||||||
/>
|
|
||||||
<BaseMarketplaceSelect
|
|
||||||
onClear={() =>
|
|
||||||
form.setFieldValue("marketplace", null)
|
|
||||||
}
|
|
||||||
clearable
|
|
||||||
placeholder={"Выберите маркетплейс"}
|
|
||||||
{...form.getInputProps("marketplace")}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<CardsTable items={data} />
|
|
||||||
<Flex direction={"row"} gap="sm">
|
|
||||||
<Button mt={10} w={"100%"} onClick={() => {
|
|
||||||
if (!selectedPrefillCard) {
|
|
||||||
notifications.error({ message: "Карточка не выбрана." });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setPrefillCard(selectedPrefillCard);
|
|
||||||
prefillOnClose();
|
|
||||||
}}>
|
|
||||||
Предзаполнить
|
|
||||||
</Button>
|
|
||||||
{
|
|
||||||
prefillCard &&
|
|
||||||
<Button mt={10} w={"100%"} variant={"outline"} onClick={() => {
|
|
||||||
setPrefillCard(undefined);
|
|
||||||
notifications.success({ message: "Предзаполнение отменено." });
|
|
||||||
prefillOnClose();
|
|
||||||
}}>
|
|
||||||
Отменить предзаполнение
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
</Flex>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Preview />
|
|
||||||
</Drawer>
|
</Drawer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
<>
|
||||||
|
<div className={styles["card-container"]}>
|
||||||
|
<div className={styles["card-container-wrapper"]}>
|
||||||
|
<div className={styles["top-panel"]}>
|
||||||
|
<TextInput
|
||||||
|
placeholder={"Введите название / id"}
|
||||||
|
value={idOrName}
|
||||||
|
onChange={e => setIdOrName(e.target.value)}
|
||||||
|
/>
|
||||||
|
<BaseMarketplaceSelect
|
||||||
|
onClear={() => setMarketplace(null)}
|
||||||
|
clearable
|
||||||
|
placeholder={"Выберите маркетплейс"}
|
||||||
|
value={marketplace || undefined}
|
||||||
|
onChange={setMarketplace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<CardsTable
|
||||||
|
items={summaries}
|
||||||
|
totalPages={totalPages}
|
||||||
|
page={page}
|
||||||
|
setPage={setPage}
|
||||||
|
/>
|
||||||
|
<Flex direction={"row"} gap="sm">
|
||||||
|
<Button mt={10} w={"100%"} onClick={() => {
|
||||||
|
if (!selectedPrefillCard) {
|
||||||
|
notifications.error({ message: "Карточка не выбрана." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPrefillCard(selectedPrefillCard);
|
||||||
|
prefillOnClose();
|
||||||
|
}}>
|
||||||
|
Предзаполнить
|
||||||
|
</Button>
|
||||||
|
{
|
||||||
|
prefillCard &&
|
||||||
|
<Button mt={10} w={"100%"} variant={"outline"} onClick={() => {
|
||||||
|
setPrefillCard(undefined);
|
||||||
|
notifications.success({ message: "Предзаполнение отменено." });
|
||||||
|
prefillOnClose();
|
||||||
|
}}>
|
||||||
|
Отменить предзаполнение
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Preview />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CardPrefillDrawerContent;
|
||||||
@@ -1,47 +1,62 @@
|
|||||||
import { FC, useEffect } from "react";
|
import { FC, useEffect, useState } from "react";
|
||||||
import useCardsTableColumns from "./columns.tsx";
|
import useCardsTableColumns from "./columns.tsx";
|
||||||
import { CardSummary } from "../../../../../../../client";
|
import { CardSummary } from "../../../../../../../client";
|
||||||
import { BaseTable } from "../../../../../../../components/BaseTable/BaseTable.tsx";
|
import { BaseTable } from "../../../../../../../components/BaseTable/BaseTable.tsx";
|
||||||
import { usePrefillCardContext } from "../../../../../contexts/PrefillCardContext.tsx";
|
import { usePrefillCardContext } from "../../../../../contexts/PrefillCardContext.tsx";
|
||||||
|
import { Group, Pagination, Stack } from "@mantine/core";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
items: CardSummary[];
|
items: CardSummary[];
|
||||||
|
totalPages: number;
|
||||||
|
page: number;
|
||||||
|
setPage: (page: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const CardsTable: FC<Props> = ({ items }) => {
|
const CardsTable: FC<Props> = ({ items, totalPages, page, setPage }) => {
|
||||||
const { selectPrefillCard } = usePrefillCardContext();
|
const { selectPrefillCard } = usePrefillCardContext();
|
||||||
const columns = useCardsTableColumns();
|
const columns = useCardsTableColumns();
|
||||||
const defaultSorting = [{ id: "createdAt", desc: false }];
|
const defaultSorting = [{ id: "createdAt", desc: false }];
|
||||||
|
const [isInitial, setIsInitial] = useState<boolean>(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (items.length < 1) return;
|
if (isInitial && items.length > 0) {
|
||||||
selectPrefillCard(items[0].id);
|
selectPrefillCard(items[0].id);
|
||||||
}, []);
|
setIsInitial(false);
|
||||||
|
}
|
||||||
|
}, [items]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseTable
|
<Stack gap={"xs"}>
|
||||||
data={items}
|
<BaseTable
|
||||||
columns={columns}
|
data={items}
|
||||||
|
columns={columns}
|
||||||
|
|
||||||
restProps={
|
restProps={
|
||||||
{
|
{
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
enableColumnActions: false,
|
enableColumnActions: false,
|
||||||
enablePagination: true,
|
paginationDisplayMode: "pages",
|
||||||
enableBottomToolbar: true,
|
initialState: {
|
||||||
paginationDisplayMode: "pages",
|
sorting: defaultSorting,
|
||||||
initialState: {
|
},
|
||||||
sorting: defaultSorting,
|
mantinePaginationProps: {
|
||||||
},
|
showRowsPerPage: false,
|
||||||
mantinePaginationProps: {
|
},
|
||||||
showRowsPerPage: false,
|
enableStickyHeader: true,
|
||||||
},
|
enableStickyFooter: true,
|
||||||
enableStickyHeader: true,
|
mantineTableContainerProps: { style: { maxHeight: "81vh", height: "81vh" } },
|
||||||
enableStickyFooter: true,
|
}
|
||||||
mantineTableContainerProps: { style: { maxHeight: "81vh", height: "81vh" } },
|
|
||||||
}
|
}
|
||||||
}
|
/>
|
||||||
/>
|
<Group justify={"flex-end"}>
|
||||||
|
<Pagination
|
||||||
|
withEdges
|
||||||
|
total={totalPages}
|
||||||
|
value={page}
|
||||||
|
onChange={setPage}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +1,58 @@
|
|||||||
import { useForm } from "@mantine/form";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { BaseMarketplaceSchema } from "../../../../../client";
|
import { BaseMarketplaceSchema } from "../../../../../client";
|
||||||
import { useCardSummariesFull } from "../../../hooks/useCardSummaries.tsx";
|
import useCardSummaries from "../../../hooks/useCardSummaries.tsx";
|
||||||
import isModuleInProject from "../../../../../modules/utils/isModuleInProject.ts";
|
import { useDebouncedValue } from "@mantine/hooks";
|
||||||
import { ModuleNames } from "../../../../../modules/modules.tsx";
|
|
||||||
|
|
||||||
type State = {
|
|
||||||
idOrName: string | null;
|
|
||||||
marketplace: BaseMarketplaceSchema | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const usePrefillCard = () => {
|
const usePrefillCard = () => {
|
||||||
const { objects } = useCardSummariesFull();
|
const [idOrName, setIdOrName] = useState<string>("");
|
||||||
const form = useForm<State>({
|
const [debouncedIdOrName] = useDebouncedValue(idOrName, 500);
|
||||||
initialValues: {
|
const prevIdOrName = useRef(idOrName);
|
||||||
idOrName: null,
|
const [marketplace, setMarketplace] = useState<BaseMarketplaceSchema | null>(null);
|
||||||
marketplace: null,
|
const prevMarketplace = useRef(marketplace);
|
||||||
},
|
|
||||||
});
|
|
||||||
const [data, setData] = useState(objects);
|
|
||||||
|
|
||||||
const applyFilters = () => {
|
const getValues = () => {
|
||||||
let result = objects;
|
let id: number | null = parseInt(debouncedIdOrName || "");
|
||||||
|
if (isNaN(id)) id = null;
|
||||||
|
|
||||||
result = result.filter(obj => isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, obj.board.project));
|
return {
|
||||||
|
cardId: id,
|
||||||
if (form.values.idOrName) {
|
cardName: id ? null : debouncedIdOrName,
|
||||||
if (isNaN(parseInt(form.values.idOrName))) {
|
marketplace,
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const {
|
||||||
applyFilters();
|
summaries,
|
||||||
}, [form.values, objects]);
|
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;
|
export default usePrefillCard;
|
||||||
|
|||||||
@@ -1,22 +1,50 @@
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
import { useState } from "react";
|
||||||
import { CardService } from "../../../client";
|
import { CardService, CardSummary } from "../../../client";
|
||||||
import ObjectList from "../../../hooks/objectList.tsx";
|
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 будет содержать либо трансформированные данные, либо пустой массив по умолчанию
|
type Props = {
|
||||||
// isLoading и isError могут быть использованы для отображения индикаторов загрузки или ошибки
|
full: boolean;
|
||||||
|
values?: CardsPageState;
|
||||||
|
withPagination?: boolean;
|
||||||
|
itemsPerPage?: number;
|
||||||
|
}
|
||||||
|
|
||||||
return { summariesRaw, refetch };
|
const useCardSummaries = ({ full, values, withPagination = false, itemsPerPage = 10 }: Props) => {
|
||||||
|
const [summaries, setSummaries] = useState<CardSummary[]>([]);
|
||||||
|
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({
|
export default useCardSummaries;
|
||||||
queryFn: () => CardService.getCardSummaries({ full: true }),
|
|
||||||
queryKey: "getCardSummariesFull",
|
|
||||||
getObjectsFn: response => response.summaries,
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -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<CardsPageState>({
|
|
||||||
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;
|
|
||||||
39
src/pages/CardsPage/hooks/useCardsTableForm.tsx
Normal file
39
src/pages/CardsPage/hooks/useCardsTableForm.tsx
Normal file
@@ -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<CardsPageState>({
|
||||||
|
initialValues: {
|
||||||
|
cardId: null,
|
||||||
|
marketplace: null,
|
||||||
|
client: null,
|
||||||
|
|
||||||
|
project: null,
|
||||||
|
board: null,
|
||||||
|
status: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { form };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useCardsTableForm;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ProjectSchema } from "../../../client";
|
import { ProjectSchema } from "../../../client";
|
||||||
import { Flex, Modal, NumberInput, rem } from "@mantine/core";
|
import { Flex, Modal, NumberInput, rem } from "@mantine/core";
|
||||||
import { UseFormReturnType } from "@mantine/form";
|
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 ObjectSelect from "../../../components/ObjectSelect/ObjectSelect.tsx";
|
||||||
import CardStatusSelect from "../../../components/CardStatusSelect/CardStatusSelect.tsx";
|
import CardStatusSelect from "../../../components/CardStatusSelect/CardStatusSelect.tsx";
|
||||||
import BaseMarketplaceSelect from "../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
|
import BaseMarketplaceSelect from "../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
|
||||||
@@ -33,7 +33,7 @@ const CardsTableFiltersModal = ({ form, projects }: Props) => {
|
|||||||
<NumberInput
|
<NumberInput
|
||||||
min={1}
|
min={1}
|
||||||
placeholder={"Введите номер"}
|
placeholder={"Введите номер"}
|
||||||
{...form.getInputProps("id")}
|
{...form.getInputProps("cardId")}
|
||||||
hideControls
|
hideControls
|
||||||
/>
|
/>
|
||||||
<ObjectSelect
|
<ObjectSelect
|
||||||
@@ -41,16 +41,16 @@ const CardsTableFiltersModal = ({ form, projects }: Props) => {
|
|||||||
data={projects}
|
data={projects}
|
||||||
clearable
|
clearable
|
||||||
searchable
|
searchable
|
||||||
{...form.getInputProps("projectForTable")}
|
{...form.getInputProps("project")}
|
||||||
onClear={() => form.setFieldValue("projectForTable", null)}
|
onClear={() => form.setFieldValue("project", null)}
|
||||||
/>
|
/>
|
||||||
<BoardSelect
|
<BoardSelect
|
||||||
project={form.values.projectForTable}
|
project={form.values.project || null}
|
||||||
{...form.getInputProps("board")}
|
{...form.getInputProps("board")}
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
<CardStatusSelect
|
<CardStatusSelect
|
||||||
board={form.values.board}
|
board={form.values.board || null}
|
||||||
{...form.getInputProps("status")}
|
{...form.getInputProps("status")}
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { FC, useMemo, useState } from "react";
|
import { FC, useEffect, useMemo, useState } from "react";
|
||||||
import { useCardSummaries } from "../hooks/useCardSummaries.tsx";
|
|
||||||
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
|
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
|
||||||
import CardEditDrawer from "../drawers/CardEditDrawer/CardEditDrawer.tsx";
|
import CardEditDrawer from "../drawers/CardEditDrawer/CardEditDrawer.tsx";
|
||||||
import { CardPageContextProvider } from "../contexts/CardPageContext.tsx";
|
import { CardPageContextProvider } from "../contexts/CardPageContext.tsx";
|
||||||
import { rem } from "@mantine/core";
|
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 CardsTable from "../components/CardsTable/CardsTable.tsx";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import CardPrefillDrawer from "../drawers/CardPrefillDrawer/CardPrefillDrawer.tsx";
|
import CardPrefillDrawer from "../drawers/CardPrefillDrawer/CardPrefillDrawer.tsx";
|
||||||
@@ -17,30 +16,35 @@ import { ProjectsEditorContextProvider } from "../contexts/ProjectsEditorContext
|
|||||||
import ProjectEditDrawer from "../drawers/ProjectEditDrawer/ProjectEditDrawer.tsx";
|
import ProjectEditDrawer from "../drawers/ProjectEditDrawer/ProjectEditDrawer.tsx";
|
||||||
import Boards from "../../../components/Dnd/Boards/Boards/Boards.tsx";
|
import Boards from "../../../components/Dnd/Boards/Boards/Boards.tsx";
|
||||||
import { DndContextProvider } from "../contexts/DndContext.tsx";
|
import { DndContextProvider } from "../contexts/DndContext.tsx";
|
||||||
|
import useCardSummaries from "../hooks/useCardSummaries.tsx";
|
||||||
|
|
||||||
export const CardsPage: FC = () => {
|
export const CardsPage: FC = () => {
|
||||||
const { data, form } = useCardsPageState();
|
const { form } = useCardsTableForm();
|
||||||
const { dealId } = useParams({ strict: false });
|
const { dealId } = useParams({ strict: false });
|
||||||
const { summariesRaw, refetch: refetchSummaries } = useCardSummaries();
|
const { summaries, fetchSummaries } = useCardSummaries({ full: false });
|
||||||
|
|
||||||
const [displayMode, setDisplayMode] = useState<DisplayMode>(DisplayMode.BOARD);
|
const [displayMode, setDisplayMode] = useState<DisplayMode>(DisplayMode.BOARD);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchSummaries();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const tableBody = useMemo(() => {
|
const tableBody = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
<CardsTable items={data} />
|
<CardsTable form={form} />
|
||||||
);
|
);
|
||||||
}, [data]);
|
}, [form]);
|
||||||
|
|
||||||
const boardsBody = useMemo(() => {
|
const boardsBody = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
<DndContextProvider
|
<DndContextProvider
|
||||||
summariesRaw={summariesRaw}
|
summariesRaw={summaries}
|
||||||
refetchSummaries={refetchSummaries}
|
refetchSummaries={fetchSummaries}
|
||||||
>
|
>
|
||||||
<Boards />
|
<Boards />
|
||||||
</DndContextProvider>
|
</DndContextProvider>
|
||||||
);
|
);
|
||||||
}, [summariesRaw]);
|
}, [summaries]);
|
||||||
|
|
||||||
const getBody = () => {
|
const getBody = () => {
|
||||||
return (
|
return (
|
||||||
@@ -72,9 +76,7 @@ export const CardsPage: FC = () => {
|
|||||||
<ProjectsEditorContextProvider>
|
<ProjectsEditorContextProvider>
|
||||||
<CardPageContextProvider
|
<CardPageContextProvider
|
||||||
defaultCardId={(dealId && parseInt(dealId)) || undefined}
|
defaultCardId={(dealId && parseInt(dealId)) || undefined}
|
||||||
refetchCards={async () => {
|
refetchCards={fetchSummaries}
|
||||||
await refetchSummaries();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<PrefillCardContextProvider>
|
<PrefillCardContextProvider>
|
||||||
<PrefillCardsWithExcelContextProvider>
|
<PrefillCardsWithExcelContextProvider>
|
||||||
|
|||||||
@@ -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<CRUDTableProps<CardSummary>, "items"> & RestProps;
|
||||||
|
|
||||||
|
const CardsTablePreview: FC<Props> = ({ shippingWarehouse, onSelectionChange }) => {
|
||||||
|
const columns = useCardsTablePreviewColumns();
|
||||||
|
|
||||||
|
const { summaries, fetchSummaries } = useCardSummaries({
|
||||||
|
full: true,
|
||||||
|
values: {
|
||||||
|
shippingWarehouse,
|
||||||
|
},
|
||||||
|
withPagination: true,
|
||||||
|
itemsPerPage: 5,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchSummaries();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseTable
|
||||||
|
data={summaries}
|
||||||
|
columns={columns}
|
||||||
|
onSelectionChange={onSelectionChange}
|
||||||
|
restProps={
|
||||||
|
{
|
||||||
|
enableSorting: true,
|
||||||
|
enableColumnActions: false,
|
||||||
|
paginationDisplayMode: "pages",
|
||||||
|
} as MRT_TableOptions<CardSummary>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CardsTablePreview;
|
||||||
@@ -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<MRT_ColumnDef<CardSummary>[]>(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
accessorKey: "id",
|
||||||
|
header: "Номер",
|
||||||
|
size: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: "Маркетплейс",
|
||||||
|
size: 10,
|
||||||
|
Cell: ({ row }) => (
|
||||||
|
<ActionIcon variant={"transparent"}>
|
||||||
|
<Image
|
||||||
|
src={row.original.baseMarketplace?.iconUrl || ""}
|
||||||
|
/>
|
||||||
|
</ActionIcon>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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;
|
||||||
@@ -3,9 +3,7 @@ import { CardSummary, ShippingWarehouseSchema } from "../../../client";
|
|||||||
import { ContextModalProps } from "@mantine/modals";
|
import { ContextModalProps } from "@mantine/modals";
|
||||||
import { useForm } from "@mantine/form";
|
import { useForm } from "@mantine/form";
|
||||||
import { Input, TextInput } from "@mantine/core";
|
import { Input, TextInput } from "@mantine/core";
|
||||||
import CardsTable from "../../CardsPage/components/CardsTable/CardsTable.tsx";
|
import CardsTablePreview from "../components/CardsTablePreview/CardsTablePreview.tsx";
|
||||||
import { CardPageContextProvider } from "../../CardsPage/contexts/CardPageContext.tsx";
|
|
||||||
import CardEditDrawer from "../../CardsPage/drawers/CardEditDrawer/CardEditDrawer.tsx";
|
|
||||||
|
|
||||||
type RestProps = {
|
type RestProps = {
|
||||||
summaries: CardSummary[];
|
summaries: CardSummary[];
|
||||||
@@ -27,34 +25,28 @@ const ShippingWarehouseForm = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<CardPageContextProvider refetchCards={async () => {}}>
|
<BaseFormModal
|
||||||
<BaseFormModal
|
{...innerProps}
|
||||||
{...innerProps}
|
closeOnSubmit
|
||||||
closeOnSubmit
|
form={form}
|
||||||
form={form}
|
onClose={() => context.closeContextModal(id)}>
|
||||||
onClose={() => context.closeContextModal(id)}>
|
<BaseFormModal.Body>
|
||||||
<BaseFormModal.Body>
|
<>
|
||||||
<>
|
<TextInput
|
||||||
<TextInput
|
label={"Склад отгрузки"}
|
||||||
label={"Склад отгрузки"}
|
placeholder={"Введите название склада отгрузки"}
|
||||||
placeholder={"Введите название склада отгрузки"}
|
{...form.getInputProps("name")}
|
||||||
{...form.getInputProps("name")}
|
/>
|
||||||
/>
|
{isEditing && (
|
||||||
{isEditing && (
|
<Input.Wrapper
|
||||||
<Input.Wrapper
|
label={"Последние 5 сделок"}
|
||||||
label={"Последние 5 сделок"}
|
error={form.getInputProps("phoneNumber").error}>
|
||||||
error={form.getInputProps("phoneNumber").error}>
|
<CardsTablePreview shippingWarehouse={form.values} />
|
||||||
<CardsTable
|
</Input.Wrapper>
|
||||||
viewOnly={true}
|
)}
|
||||||
items={innerProps.summaries}
|
</>
|
||||||
/>
|
</BaseFormModal.Body>
|
||||||
</Input.Wrapper>
|
</BaseFormModal>
|
||||||
)}
|
|
||||||
</>
|
|
||||||
</BaseFormModal.Body>
|
|
||||||
</BaseFormModal>
|
|
||||||
<CardEditDrawer />
|
|
||||||
</CardPageContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
import styles from "../../ServicesPage/ui/ServicesPage.module.css";
|
import styles from "../../ServicesPage/ui/ServicesPage.module.css";
|
||||||
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
|
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
|
||||||
import ShippingWarehousesTable from "../components/ShippingWarehousesTable/ShippingWarehousesTable.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 { Button } from "@mantine/core";
|
||||||
import { modals } from "@mantine/modals";
|
import { modals } from "@mantine/modals";
|
||||||
import { useCRUD } from "../../../hooks/useCRUD.tsx";
|
import { useCRUD } from "../../../hooks/useCRUD.tsx";
|
||||||
import {
|
import { ShippingWarehouseSchema, ShippingWarehouseService } from "../../../client";
|
||||||
ShippingWarehouseSchema,
|
|
||||||
ShippingWarehouseService,
|
|
||||||
} from "../../../client";
|
|
||||||
import { notifications } from "../../../shared/lib/notifications.ts";
|
import { notifications } from "../../../shared/lib/notifications.ts";
|
||||||
import { useCardSummariesFull } from "../../CardsPage/hooks/useCardSummaries.tsx";
|
import useCardSummaries from "../../CardsPage/hooks/useCardSummaries.tsx";
|
||||||
|
|
||||||
export const ShippingWarehousesPage = () => {
|
export const ShippingWarehousesPage = () => {
|
||||||
const { shippingWarehouses, refetch } = useShippingWarehousesList();
|
const { shippingWarehouses, refetch } = useShippingWarehousesList();
|
||||||
const { objects: summaries } = useCardSummariesFull();
|
const { summaries } = useCardSummaries({
|
||||||
|
full: true,
|
||||||
|
withPagination: true,
|
||||||
|
values: {},
|
||||||
|
});
|
||||||
|
|
||||||
const crud = useCRUD<ShippingWarehouseSchema>({
|
const crud = useCRUD<ShippingWarehouseSchema>({
|
||||||
onChange: element => {
|
onChange: element => {
|
||||||
ShippingWarehouseService.updateShippingWarehouse({
|
ShippingWarehouseService.updateShippingWarehouse({
|
||||||
|
|||||||
Reference in New Issue
Block a user