feat: searchable product select and department select
This commit is contained in:
@@ -73,6 +73,7 @@ const DepartmentSelect = ({
|
||||
value={getDepartmentValue()}
|
||||
onChange={setDepartmentValue}
|
||||
label={"Родительский департамент/отдел"}
|
||||
searchable
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { ProductSchema } from "../../../../../client";
|
||||
import { FC, useState } from "react";
|
||||
import ObjectSelect, { ObjectSelectProps } from "../../../../../components/ObjectSelect/ObjectSelect.tsx";
|
||||
import getRenderOptions from "../../../../../components/ProductSelect/utils/getRenderOptions.tsx";
|
||||
|
||||
|
||||
type Props = Omit<ObjectSelectProps<ProductSchema>, "searchValue" | "onSearchChange">;
|
||||
|
||||
const ShippingProductSelect: FC<Props> = (props: Props) => {
|
||||
const [search, setSearch] = useState("");
|
||||
|
||||
const getFilteredData = () => {
|
||||
const searchValue: string = search.toLowerCase();
|
||||
|
||||
const data: ProductSchema[] = props.data.filter(product => {
|
||||
return (
|
||||
product.name.toLowerCase().includes(searchValue) ||
|
||||
product.article?.toLowerCase().includes(searchValue) ||
|
||||
product.barcodes && product.barcodes[0].toLowerCase().includes(searchValue)
|
||||
);
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
return (
|
||||
<ObjectSelect
|
||||
label={"Товар"}
|
||||
placeholder={"Выберите товар"}
|
||||
searchable
|
||||
{...props}
|
||||
data={getFilteredData()}
|
||||
searchValue={search}
|
||||
onSearchChange={setSearch}
|
||||
renderOption={getRenderOptions(props.data)}
|
||||
filter={({ options }) => options}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShippingProductSelect;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useForm } from "@mantine/form";
|
||||
import { ContextModalProps } from "@mantine/modals";
|
||||
import { Button, Flex, NumberInput, rem, Select, Text } from "@mantine/core";
|
||||
import { Button, Flex, NumberInput, rem, Text } from "@mantine/core";
|
||||
import getRestProducts from "../utils/getRestProducts.tsx";
|
||||
import {
|
||||
CreateBoxInDealSchema,
|
||||
@@ -8,14 +8,15 @@ import {
|
||||
CreateShippingProductSchema,
|
||||
DealProductSchema,
|
||||
DealSchema,
|
||||
ProductSchema,
|
||||
ShippingService,
|
||||
UpdateBoxSchema,
|
||||
UpdateShippingProductSchema,
|
||||
} from "../../../../../client";
|
||||
import { notifications } from "../../../../../shared/lib/notifications.ts";
|
||||
import { ShippingData, ShippingModalForm, ShippingProductOption } from "../types/ShippingProductData.tsx";
|
||||
import { ShippingData, ShippingModalForm } from "../types/ShippingProductData.tsx";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import ShippingProductSelect from "../components/ShippingProductSelect.tsx";
|
||||
|
||||
|
||||
type Props = {
|
||||
@@ -31,11 +32,11 @@ const ShippingProductModal = ({
|
||||
innerProps,
|
||||
}: ContextModalProps<Props>) => {
|
||||
const [restProducts, setRestProducts] = useState<Map<number, DealProductSchema>>(new Map());
|
||||
const [restProductsSelectData, setRestProductSelectData] = useState<ShippingProductOption[]>([]);
|
||||
const [restProductsSelectData, setRestProductSelectData] = useState<ProductSchema[]>([]);
|
||||
|
||||
const getRestProductQuantity = () => {
|
||||
if (form.values.productId) {
|
||||
const restProduct = restProducts.get(Number(form.values.productId));
|
||||
if (form.values.product) {
|
||||
const restProduct = restProducts.get(form.values.product.id);
|
||||
if (restProduct) {
|
||||
return restProduct.quantity;
|
||||
}
|
||||
@@ -43,14 +44,19 @@ const ShippingProductModal = ({
|
||||
return 10000;
|
||||
};
|
||||
|
||||
const findProductById = (productId?: number | null) => {
|
||||
const dealProduct = innerProps.deal.products.find(p => p.product.id === productId);
|
||||
return dealProduct ? dealProduct.product : null;
|
||||
};
|
||||
|
||||
const initialValues: ShippingModalForm = {
|
||||
quantity: innerProps.shippingData.quantity ?? 0,
|
||||
productId: innerProps.shippingData.productId,
|
||||
product: findProductById(innerProps.shippingData.productId),
|
||||
};
|
||||
const form = useForm<ShippingModalForm>({
|
||||
initialValues,
|
||||
validate: {
|
||||
productId: productId => !productId && "Необходимо выбрать товар",
|
||||
product: product => !product && "Необходимо выбрать товар",
|
||||
quantity: quantity => quantity > getRestProductQuantity() ? "Слишком много товара" :
|
||||
quantity === 0 && "Слишком мало товара",
|
||||
},
|
||||
@@ -69,6 +75,7 @@ const ShippingProductModal = ({
|
||||
const data = {
|
||||
...innerProps.shippingData,
|
||||
...form.values,
|
||||
productId: form.values.product?.id,
|
||||
} as CreateBoxInPalletSchema | CreateBoxInDealSchema | UpdateBoxSchema;
|
||||
|
||||
ShippingService.updateBox({
|
||||
@@ -86,6 +93,7 @@ const ShippingProductModal = ({
|
||||
const data = {
|
||||
...innerProps.shippingData,
|
||||
...form.values,
|
||||
productId: form.values.product?.id,
|
||||
} as CreateShippingProductSchema | UpdateShippingProductSchema;
|
||||
|
||||
ShippingService.updateShippingProduct({
|
||||
@@ -108,7 +116,7 @@ const ShippingProductModal = ({
|
||||
};
|
||||
|
||||
const getRestQuantityText = () => {
|
||||
if (!form.values.productId) return;
|
||||
if (!form.values.product) return;
|
||||
|
||||
const restQuantityInDeal = getRestProductQuantity();
|
||||
const restQuantity = restQuantityInDeal - form.values.quantity;
|
||||
@@ -125,12 +133,9 @@ const ShippingProductModal = ({
|
||||
direction={"column"}
|
||||
gap={rem(10)}
|
||||
>
|
||||
<Select
|
||||
<ShippingProductSelect
|
||||
{...form.getInputProps("product")}
|
||||
data={restProductsSelectData}
|
||||
label={"Товар"}
|
||||
placeholder={"Выберите товар"}
|
||||
{...form.getInputProps("productId")}
|
||||
value={form.values.productId?.toString()}
|
||||
/>
|
||||
|
||||
{getRestQuantityText()}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { CreateShippingProductSchema, UpdateBoxSchema, UpdateShippingProductSchema } from "../../../../../client";
|
||||
import {
|
||||
CreateShippingProductSchema,
|
||||
ProductSchema,
|
||||
UpdateBoxSchema,
|
||||
UpdateShippingProductSchema,
|
||||
} from "../../../../../client";
|
||||
|
||||
export type ShippingModalForm = {
|
||||
quantity: number;
|
||||
productId?: number | null;
|
||||
}
|
||||
|
||||
export type ShippingProductOption = {
|
||||
value: string;
|
||||
label: string;
|
||||
product?: ProductSchema | null;
|
||||
}
|
||||
|
||||
export type ShippingData =
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ShippingProductOption } from "../types/ShippingProductData.tsx";
|
||||
import { DealProductSchema, DealSchema, ProductSchema } from "../../../../../client";
|
||||
|
||||
type UnaccountedValues = {
|
||||
@@ -61,11 +60,11 @@ const getRestProducts = ({
|
||||
}
|
||||
});
|
||||
|
||||
const restProductsSelectData: ShippingProductOption[] = [];
|
||||
const restProductsSelectData: ProductSchema[] = [];
|
||||
|
||||
restProducts.forEach(
|
||||
(restProduct, id) => {
|
||||
restProductsSelectData.push({ value: String(id), label: restProduct.product.name });
|
||||
(restProduct) => {
|
||||
restProductsSelectData.push(restProduct.product);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user