From 311210394fd72e4d656e86beeafcb7b009c77bb7 Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Mon, 3 Nov 2025 10:42:13 +0400 Subject: [PATCH] fix: fixed showing default option label --- .../components}/AttrOptionSelect.tsx | 8 ++-- .../components/AttributeValueInput.tsx | 2 +- .../useAttributesTableColumns.tsx | 8 ++-- .../DefaultAttrOptionSelect.tsx | 29 +++++++++++++ .../DefaultAttributeValueInput.tsx | 13 +++--- .../components/shared/PageBody/PageBody.tsx | 2 + .../[moduleId]/hooks/useAttributesCrud.tsx | 7 ++-- .../modals/AttributeEditorModal.tsx | 10 ++++- .../hooks/useAttributesInnerTableColumns.tsx | 2 +- .../AttributeDefaultValue.tsx | 6 ++- .../lists}/useAttributeOptionsList.ts | 0 src/lib/client/client/utils.ts | 4 +- src/lib/client/types.gen.ts | 42 +++++++++---------- src/lib/client/zod.gen.ts | 25 +++++------ 14 files changed, 98 insertions(+), 60 deletions(-) rename src/app/{module-editor/[moduleId]/components/shared/AttrOptionSelect => deals/drawers/DealEditorDrawer/components}/AttrOptionSelect.tsx (82%) create mode 100644 src/app/module-editor/[moduleId]/components/shared/DefaultAttrOptionSelect/DefaultAttrOptionSelect.tsx rename src/{app/module-editor/[moduleId]/components/shared/AttrOptionSelect => hooks/lists}/useAttributeOptionsList.ts (100%) diff --git a/src/app/module-editor/[moduleId]/components/shared/AttrOptionSelect/AttrOptionSelect.tsx b/src/app/deals/drawers/DealEditorDrawer/components/AttrOptionSelect.tsx similarity index 82% rename from src/app/module-editor/[moduleId]/components/shared/AttrOptionSelect/AttrOptionSelect.tsx rename to src/app/deals/drawers/DealEditorDrawer/components/AttrOptionSelect.tsx index 4772b72..de603af 100644 --- a/src/app/module-editor/[moduleId]/components/shared/AttrOptionSelect/AttrOptionSelect.tsx +++ b/src/app/deals/drawers/DealEditorDrawer/components/AttrOptionSelect.tsx @@ -1,11 +1,11 @@ import { useEffect, useState } from "react"; import { omit } from "lodash"; -import useAttributeOptionsList from "@/app/module-editor/[moduleId]/components/shared/AttrOptionSelect/useAttributeOptionsList"; import ObjectSelect from "@/components/selects/ObjectSelect/ObjectSelect"; +import useAttributeOptionsList from "@/hooks/lists/useAttributeOptionsList"; import { AttrOptionSchema } from "@/lib/client"; type Props = { - value: any; + value: number; onChange: (val: any) => void; selectId: number; error?: string; @@ -22,7 +22,7 @@ const AttrOptionSelect = (props: Props) => { setSelectedOption(undefined); return; } - setSelectedOption(options.find(option => option.value === props.value)); + setSelectedOption(options.find(option => option.id === props.value)); }, [props.value, options]); const restProps = omit(props, ["value, onChange", "selectId"]); @@ -35,7 +35,7 @@ const AttrOptionSelect = (props: Props) => { value={selectedOption} onChange={option => { setSelectedOption(option); - props.onChange(option.value); + props.onChange(option.id); }} onClear={() => { setSelectedOption(undefined); diff --git a/src/app/deals/drawers/DealEditorDrawer/components/AttributeValueInput.tsx b/src/app/deals/drawers/DealEditorDrawer/components/AttributeValueInput.tsx index 9f8e2a9..5d2192b 100644 --- a/src/app/deals/drawers/DealEditorDrawer/components/AttributeValueInput.tsx +++ b/src/app/deals/drawers/DealEditorDrawer/components/AttributeValueInput.tsx @@ -1,7 +1,7 @@ import { CSSProperties, FC, JSX } from "react"; import { Checkbox, NumberInput, TextInput } from "@mantine/core"; import { DatePickerInput, DateTimePicker } from "@mantine/dates"; -import AttrOptionSelect from "@/app/module-editor/[moduleId]/components/shared/AttrOptionSelect/AttrOptionSelect"; +import AttrOptionSelect from "@/app/deals/drawers/DealEditorDrawer/components/AttrOptionSelect"; import { DealModuleAttributeSchema } from "@/lib/client"; import { naiveDateTimeStringToUtc } from "@/utils/datetime"; diff --git a/src/app/module-editor/[moduleId]/components/shared/AttributesTable/useAttributesTableColumns.tsx b/src/app/module-editor/[moduleId]/components/shared/AttributesTable/useAttributesTableColumns.tsx index 792d8c0..fa4b5f0 100644 --- a/src/app/module-editor/[moduleId]/components/shared/AttributesTable/useAttributesTableColumns.tsx +++ b/src/app/module-editor/[moduleId]/components/shared/AttributesTable/useAttributesTableColumns.tsx @@ -3,14 +3,14 @@ import { useMemo } from "react"; import { DataTableColumn } from "mantine-datatable"; import { Center } from "@mantine/core"; -import { useAttributesContext } from "@/app/attributes/contexts/AttributesContext"; import AttributeTableActions from "@/app/module-editor/[moduleId]/components/shared/AttributeTableActions/AttributeTableActions"; +import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext"; import useIsMobile from "@/hooks/utils/useIsMobile"; import { AttributeSchema } from "@/lib/client"; const useAttributesTableColumns = () => { const isMobile = useIsMobile(); - const { attributesActions } = useAttributesContext(); + const { attributeActions } = useModuleEditorContext(); return useMemo( () => @@ -24,7 +24,7 @@ const useAttributesTableColumns = () => { accessor: "type.name", render: attr => attr.type.type === "select" - ? `Выбор "${attr.label}"` + ? `Выбор "${attr.select?.label}"` : attr.type.name, }, { @@ -34,7 +34,7 @@ const useAttributesTableColumns = () => { render: attribute => ( ), }, diff --git a/src/app/module-editor/[moduleId]/components/shared/DefaultAttrOptionSelect/DefaultAttrOptionSelect.tsx b/src/app/module-editor/[moduleId]/components/shared/DefaultAttrOptionSelect/DefaultAttrOptionSelect.tsx new file mode 100644 index 0000000..074112f --- /dev/null +++ b/src/app/module-editor/[moduleId]/components/shared/DefaultAttrOptionSelect/DefaultAttrOptionSelect.tsx @@ -0,0 +1,29 @@ +import ObjectSelect from "@/components/selects/ObjectSelect/ObjectSelect"; +import useAttributeOptionsList from "@/hooks/lists/useAttributeOptionsList"; +import { AttrOptionSchema } from "@/lib/client"; + +type Props = { + value?: AttrOptionSchema | null; + onChange: (val: AttrOptionSchema | null) => void; + selectId: number; + error?: string; + label?: string; +}; + +const DefaultAttrOptionSelect = ({ selectId, ...props }: Props) => { + const { options } = useAttributeOptionsList({ selectId }); + + return ( + props.onChange(null)} + getLabelFn={(option: AttrOptionSchema) => option.label} + clearable + searchable + /> + ); +}; + +export default DefaultAttrOptionSelect; diff --git a/src/app/module-editor/[moduleId]/components/shared/DefaultAttributeValueInput/DefaultAttributeValueInput.tsx b/src/app/module-editor/[moduleId]/components/shared/DefaultAttributeValueInput/DefaultAttributeValueInput.tsx index b86cfff..dff0c83 100644 --- a/src/app/module-editor/[moduleId]/components/shared/DefaultAttributeValueInput/DefaultAttributeValueInput.tsx +++ b/src/app/module-editor/[moduleId]/components/shared/DefaultAttributeValueInput/DefaultAttributeValueInput.tsx @@ -1,7 +1,7 @@ import { Checkbox, NumberInput, TextInput } from "@mantine/core"; import { DatePickerInput, DateTimePicker } from "@mantine/dates"; import { UseFormReturnType } from "@mantine/form"; -import AttrOptionSelect from "@/app/module-editor/[moduleId]/components/shared/AttrOptionSelect/AttrOptionSelect"; +import DefaultAttrOptionSelect from "@/app/module-editor/[moduleId]/components/shared/DefaultAttrOptionSelect/DefaultAttrOptionSelect"; import { AttributeSchema } from "@/lib/client"; import { naiveDateTimeStringToUtc } from "@/utils/datetime"; @@ -91,11 +91,14 @@ const DefaultAttributeValueInput = ({ form }: Props) => { } else if (type === "select") { if (!form.values.select?.id) return <>; return ( - form.setFieldValue("defaultValue", value)} + {...form.getInputProps("defaultOption")} + value={form.values.defaultOption} + onChange={value => { + form.setFieldValue("defaultOption", value); + form.setFieldValue("defaultOptionId", value?.id); + }} selectId={form.values.select?.id} /> ); diff --git a/src/app/module-editor/[moduleId]/components/shared/PageBody/PageBody.tsx b/src/app/module-editor/[moduleId]/components/shared/PageBody/PageBody.tsx index 17b6134..efa7bec 100644 --- a/src/app/module-editor/[moduleId]/components/shared/PageBody/PageBody.tsx +++ b/src/app/module-editor/[moduleId]/components/shared/PageBody/PageBody.tsx @@ -11,6 +11,8 @@ import PageBlock from "@/components/layout/PageBlock/PageBlock"; const PageBody = () => { const { module } = useModuleEditorContext(); + if (!module) return; + return ( ), validate: { label: label => !label?.trim() && "Название не заполнено", type: type => !type && "Тип атрибута не выбран", - defaultValue: (defaultValue, values) => { - if (defaultValue === null && !values.isNullable) { + isNullable: (isNullable, values) => { + if ( + values.defaultValue === null && + values.defaultOption === null && + !isNullable + ) { return "Укажите значение по умолчанию или разрешите пустое значение."; } return false; diff --git a/src/app/modules/hooks/useAttributesInnerTableColumns.tsx b/src/app/modules/hooks/useAttributesInnerTableColumns.tsx index 6426d02..25675f4 100644 --- a/src/app/modules/hooks/useAttributesInnerTableColumns.tsx +++ b/src/app/modules/hooks/useAttributesInnerTableColumns.tsx @@ -25,7 +25,7 @@ const useAttributesInnerTableColumns = () => { accessor: "type.name", render: attr => attr.type.type === "select" - ? `Выбор "${attr.label}"` + ? `Выбор "${attr.select?.label}"` : attr.type.name, }, { diff --git a/src/components/ui/AttributeDefaultValue/AttributeDefaultValue.tsx b/src/components/ui/AttributeDefaultValue/AttributeDefaultValue.tsx index 68515a8..573bf68 100644 --- a/src/components/ui/AttributeDefaultValue/AttributeDefaultValue.tsx +++ b/src/components/ui/AttributeDefaultValue/AttributeDefaultValue.tsx @@ -12,9 +12,8 @@ type Props = { }; const AttributeDefaultValue: FC = ({ attribute }) => { - if (!attribute.defaultValue) return <>-; + if (!attribute.defaultValue && !attribute.defaultOption) return <>-; const value = attribute.defaultValue; - if (value === null) return <>-; const type = attribute.type.type; if (type === "datetime") { @@ -28,6 +27,9 @@ const AttributeDefaultValue: FC = ({ attribute }) => { if (type === "bool") { return value ? : ; } + if (type === "select") { + return attribute.defaultOption?.label; + } return <>{value}; }; diff --git a/src/app/module-editor/[moduleId]/components/shared/AttrOptionSelect/useAttributeOptionsList.ts b/src/hooks/lists/useAttributeOptionsList.ts similarity index 100% rename from src/app/module-editor/[moduleId]/components/shared/AttrOptionSelect/useAttributeOptionsList.ts rename to src/hooks/lists/useAttributeOptionsList.ts diff --git a/src/lib/client/client/utils.ts b/src/lib/client/client/utils.ts index f202217..8d86d8a 100644 --- a/src/lib/client/client/utils.ts +++ b/src/lib/client/client/utils.ts @@ -266,9 +266,9 @@ export const mergeHeaders = ( delete mergedHeaders[key]; } else if (Array.isArray(value)) { for (const v of value) { - // @ts-ignore + // @ts-expect-error mergedHeaders[key] = [ - ...(mergedHeaders[key] ?? []) as any, + ...(mergedHeaders[key] ?? []), v as string, ]; } diff --git a/src/lib/client/types.gen.ts b/src/lib/client/types.gen.ts index 8259f31..23d139a 100644 --- a/src/lib/client/types.gen.ts +++ b/src/lib/client/types.gen.ts @@ -22,10 +22,6 @@ export type AttrOptionSchema = { * Label */ label: string; - /** - * Value - */ - value: unknown; }; /** @@ -66,6 +62,10 @@ export type AttributeSchema = { * Defaultvalue */ defaultValue: unknown | null; + /** + * Defaultoptionid + */ + defaultOptionId?: number | null; /** * Description */ @@ -87,21 +87,8 @@ export type AttributeSchema = { */ isBuiltIn: boolean; type: AttributeTypeSchema; - select: AttributeSelectSchema | null; -}; - -/** - * AttributeSelectSchema - */ -export type AttributeSelectSchema = { - /** - * Id - */ - id: number; - /** - * Label - */ - label: string; + defaultOption?: AttrOptionSchema | null; + select: AttrSelectSchema | null; }; /** @@ -345,6 +332,10 @@ export type CreateAttributeSchema = { * Defaultvalue */ defaultValue: unknown | null; + /** + * Defaultoptionid + */ + defaultOptionId?: number | null; /** * Description */ @@ -1084,7 +1075,7 @@ export type DealModuleAttributeSchema = { */ value: unknown | null; type: AttributeTypeSchema; - select: AttributeSelectSchema | null; + select: AttrSelectSchema | null; /** * Defaultvalue */ @@ -1847,6 +1838,10 @@ export type ModuleAttributeSchema = { * Defaultvalue */ defaultValue: unknown | null; + /** + * Defaultoptionid + */ + defaultOptionId?: number | null; /** * Description */ @@ -1868,7 +1863,8 @@ export type ModuleAttributeSchema = { */ isBuiltIn: boolean; type: AttributeTypeSchema; - select: AttributeSelectSchema | null; + defaultOption?: AttrOptionSchema | null; + select: AttrSelectSchema | null; /** * Originallabel */ @@ -2454,6 +2450,10 @@ export type UpdateAttributeSchema = { * Defaultvalue */ defaultValue?: unknown | null; + /** + * Defaultoptionid + */ + defaultOptionId?: number | null; /** * Description */ diff --git a/src/lib/client/zod.gen.ts b/src/lib/client/zod.gen.ts index c3bb95e..29e2fca 100644 --- a/src/lib/client/zod.gen.ts +++ b/src/lib/client/zod.gen.ts @@ -15,7 +15,6 @@ export const zAddAttributeResponse = z.object({ export const zAttrOptionSchema = z.object({ id: z.int(), label: z.string(), - value: z.unknown(), }); /** @@ -36,14 +35,6 @@ export const zAttributeTypeSchema = z.object({ name: z.string(), }); -/** - * AttributeSelectSchema - */ -export const zAttributeSelectSchema = z.object({ - id: z.int(), - label: z.string(), -}); - /** * AttributeSchema */ @@ -52,13 +43,15 @@ export const zAttributeSchema = z.object({ isApplicableToGroup: z.boolean(), isNullable: z.boolean(), defaultValue: z.union([z.unknown(), z.null()]), + defaultOptionId: z.optional(z.union([z.int(), z.null()])), description: z.string(), typeId: z.int(), selectId: z.optional(z.union([z.int(), z.null()])), id: z.int(), isBuiltIn: z.boolean(), type: zAttributeTypeSchema, - select: z.union([zAttributeSelectSchema, z.null()]), + defaultOption: z.optional(z.union([zAttrOptionSchema, z.null()])), + select: z.union([zAttrSelectSchema, z.null()]), }); /** @@ -122,14 +115,14 @@ export const zBoardSchema = z.object({ * Body_upload_product_barcode_image */ export const zBodyUploadProductBarcodeImage = z.object({ - upload_file: z.any(), + upload_file: z.string(), }); /** * Body_upload_product_image */ export const zBodyUploadProductImage = z.object({ - upload_file: z.any(), + upload_file: z.string(), }); /** @@ -162,6 +155,7 @@ export const zCreateAttributeSchema = z.object({ isApplicableToGroup: z.boolean(), isNullable: z.boolean(), defaultValue: z.union([z.unknown(), z.null()]), + defaultOptionId: z.optional(z.union([z.int(), z.null()])), description: z.string(), typeId: z.int(), selectId: z.optional(z.union([z.int(), z.null()])), @@ -854,7 +848,7 @@ export const zDealModuleAttributeSchema = z.object({ originalLabel: z.string(), value: z.union([z.unknown(), z.null()]), type: zAttributeTypeSchema, - select: z.union([zAttributeSelectSchema, z.null()]), + select: z.union([zAttrSelectSchema, z.null()]), defaultValue: z.unknown(), description: z.string(), isApplicableToGroup: z.boolean(), @@ -1053,13 +1047,15 @@ export const zModuleAttributeSchema = z.object({ isApplicableToGroup: z.boolean(), isNullable: z.boolean(), defaultValue: z.union([z.unknown(), z.null()]), + defaultOptionId: z.optional(z.union([z.int(), z.null()])), description: z.string(), typeId: z.int(), selectId: z.optional(z.union([z.int(), z.null()])), id: z.int(), isBuiltIn: z.boolean(), type: zAttributeTypeSchema, - select: z.union([zAttributeSelectSchema, z.null()]), + defaultOption: z.optional(z.union([zAttrOptionSchema, z.null()])), + select: z.union([zAttrSelectSchema, z.null()]), originalLabel: z.string(), }); @@ -1389,6 +1385,7 @@ export const zUpdateAttributeSchema = z.object({ isApplicableToGroup: z.optional(z.union([z.boolean(), z.null()])), isNullable: z.optional(z.union([z.boolean(), z.null()])), defaultValue: z.optional(z.union([z.unknown(), z.null()])), + defaultOptionId: z.optional(z.union([z.int(), z.null()])), description: z.optional(z.union([z.string(), z.null()])), });