fix: attribute editors fixes

This commit is contained in:
2025-03-03 10:45:54 +04:00
parent e151e4bc5e
commit 9ef057f889
6 changed files with 119 additions and 59 deletions

View File

@@ -1,8 +1,9 @@
import { AttributeSchema } from "../../../client"; import { AttributeSchema } from "../../../client";
import { Checkbox, NumberInput, TextInput } from "@mantine/core"; import { Checkbox, Group, NumberInput, TextInput, Tooltip } from "@mantine/core";
import { UseFormReturnType } from "@mantine/form"; import { UseFormReturnType } from "@mantine/form";
import { DatePickerInput, DateTimePicker } from "@mantine/dates"; import { DatePickerInput, DateTimePicker } from "@mantine/dates";
import { CardGeneralFormType } from "../../../pages/CardsPage/tabs/GeneralTab/GeneralTab.tsx"; import { CardGeneralFormType } from "../../../pages/CardsPage/tabs/GeneralTab/GeneralTab.tsx";
import { IconInfoCircle } from "@tabler/icons-react";
type Props = { type Props = {
attribute: AttributeSchema; attribute: AttributeSchema;
@@ -18,22 +19,29 @@ const CardAttributeField = ({ attribute, form }: Props) => {
return new Date(value); return new Date(value);
}; };
const labelData = { const label = (
label: attribute.label, <Group gap={5} align={"flex-start"}>
description: attribute.description, {attribute.label}
}; {attribute.description && (
<Tooltip label={attribute.description} withArrow>
<IconInfoCircle size={18} />
</Tooltip>
)}
</Group>
);
if (type === "bool") { if (type === "bool") {
return ( return (
<Checkbox <Checkbox
{...labelData} label={label}
{...form.getInputProps(attribute.name, { type: "checkbox" })} {...form.getInputProps(attribute.name, { type: "checkbox" })}
/> />
); );
} else if (type === "date") { }
if (type === "date") {
return ( return (
<DatePickerInput <DatePickerInput
{...labelData} label={label}
{...form.getInputProps(attribute.name)} {...form.getInputProps(attribute.name)}
value={getDateValue()} value={getDateValue()}
clearable clearable
@@ -41,10 +49,11 @@ const CardAttributeField = ({ attribute, form }: Props) => {
valueFormat="DD.MM.YYYY" valueFormat="DD.MM.YYYY"
/> />
); );
} else if (type === "datetime") { }
if (type === "datetime") {
return ( return (
<DateTimePicker <DateTimePicker
{...labelData} label={label}
{...form.getInputProps(attribute.name)} {...form.getInputProps(attribute.name)}
value={getDateValue()} value={getDateValue()}
clearable clearable
@@ -52,19 +61,21 @@ const CardAttributeField = ({ attribute, form }: Props) => {
valueFormat="DD.MM.YYYY HH:mm" valueFormat="DD.MM.YYYY HH:mm"
/> />
); );
} else if (type === "str") { }
if (type === "str") {
return ( return (
<TextInput <TextInput
{...labelData} label={label}
{...form.getInputProps(attribute.name)} {...form.getInputProps(attribute.name)}
value={form.getInputProps(attribute.name).value ?? ""} value={form.getInputProps(attribute.name).value ?? ""}
/> />
); );
} else if (type === "int" || type === "float") { }
if (type === "int" || type === "float") {
return ( return (
<NumberInput <NumberInput
allowDecimal={type === "float"} allowDecimal={type === "float"}
{...labelData} label={label}
{...form.getInputProps(attribute.name)} {...form.getInputProps(attribute.name)}
/> />
); );

View File

@@ -55,7 +55,7 @@ const DefaultAttributeValueInput = ({ form }: Props) => {
allowDecimal={type === "float"} allowDecimal={type === "float"}
label={label} label={label}
{...form.getInputProps(inputName)} {...form.getInputProps(inputName)}
value={Number(form.values.defaultValue)} value={form.values.defaultValue ? Number(form.values.defaultValue) : undefined}
/> />
) )
} }

View File

@@ -3,6 +3,7 @@ import { MRT_ColumnDef } from "mantine-react-table";
import { AttributeSchema } from "../../../../../client"; import { AttributeSchema } from "../../../../../client";
import { IconCheck, IconX } from "@tabler/icons-react"; import { IconCheck, IconX } from "@tabler/icons-react";
import { formatDate, formatDateTime } from "../../../../../types/utils.ts"; import { formatDate, formatDateTime } from "../../../../../types/utils.ts";
import { Box } from "@mantine/core";
const useAttributesTableColumns = () => { const useAttributesTableColumns = () => {
@@ -58,7 +59,8 @@ const useAttributesTableColumns = () => {
{ {
header: "Описаниие", header: "Описаниие",
accessorKey: "description", accessorKey: "description",
} Cell: ({ row }) => <Box>{row.original.description}</Box>,
},
], ],
[], [],
); );

View File

@@ -22,7 +22,7 @@ const AttributeModal = ({
const isEditing = "attribute" in innerProps; const isEditing = "attribute" in innerProps;
const [isInitial, setIsInitial] = useState(true); const [isInitial, setIsInitial] = useState(true);
const [isNullableInputShown, setIsNullableInputShown] = useState(true); const [isNullableInputShown, setIsNullableInputShown] = useState(true);
const [isDefaultValueInputShown, setIsDefaultValueInputShown] = useState(true); const [copyTypeId, setCopyTypeId] = useState<number>();
const closeModal = () => context.closeContextModal(id); const closeModal = () => context.closeContextModal(id);
const form = useForm<Partial<AttributeSchema>>({ const form = useForm<Partial<AttributeSchema>>({
@@ -49,7 +49,6 @@ const AttributeModal = ({
}, [form.values.label]); }, [form.values.label]);
useEffect(() => { useEffect(() => {
setIsDefaultValueInputShown(false);
const type = form.values.type?.type; const type = form.values.type?.type;
setIsNullableInputShown(type !== "bool"); setIsNullableInputShown(type !== "bool");
@@ -62,7 +61,7 @@ const AttributeModal = ({
} }
} }
setIsInitial(false); setIsInitial(false);
setIsDefaultValueInputShown(true); setCopyTypeId(form.values.type?.id);
}, [form.values.type?.id]); }, [form.values.type?.id]);
const validate = (): boolean => { const validate = (): boolean => {
@@ -150,7 +149,7 @@ const AttributeModal = ({
{...form.getInputProps("isNullable", { type: "checkbox" })} {...form.getInputProps("isNullable", { type: "checkbox" })}
/> />
)} )}
{form.values.type && isDefaultValueInputShown && ( {form.values.type && copyTypeId === form.values.type.id && (
<DefaultAttributeValueInput form={form} /> <DefaultAttributeValueInput form={form} />
)} )}
<Textarea <Textarea

View File

@@ -1,9 +1,9 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { MRT_ColumnDef } from "mantine-react-table"; import { MRT_ColumnDef } from "mantine-react-table";
import { AttributeSchema } from "../../../../../../../client"; import { AttributeSchema } from "../../../../../../../client";
import { Box, Center, Checkbox, rem, Text, Tooltip } from "@mantine/core"; import { Box, Center, Checkbox } from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react"; import { IconCheck, IconX } from "@tabler/icons-react";
import defaultValueToStr from "../../../utils/defaultValueToStr.ts"; import { formatDate, formatDateTime } from "../../../../../../../types/utils.ts";
type Props = { type Props = {
@@ -13,36 +13,6 @@ type Props = {
const useAttributesTableColumns = ({ selectedAttributes }: Props) => { const useAttributesTableColumns = ({ selectedAttributes }: Props) => {
return useMemo<MRT_ColumnDef<AttributeSchema>[]>( return useMemo<MRT_ColumnDef<AttributeSchema>[]>(
() => [ () => [
{
header: "Название",
accessorKey: "label",
size: 25,
},
{
header: "Тип",
accessorKey: "type.name",
size: 25,
},
{
header: " ",
Cell: ({ row }) => {
const description = row.original.description ? `Описание: ${row.original.description}` : "";
const info = (
<Box>
<Text>Может быть пустым: {row.original.isNullable ? "да" : "нет"}</Text>
<Text>{defaultValueToStr(row.original.defaultValue, row.original.type.type)}</Text>
<Text>Синхронизировано в группе: {row.original.isApplicableToGroup ? "да" : "нет"}</Text>
<Text>{description}</Text>
</Box>
);
return (
<Tooltip label={info} multiline w={rem(300)}>
<IconInfoCircle />
</Tooltip>
);
},
size: 5,
},
{ {
header: " ", header: " ",
Cell: ({ row }) => ( Cell: ({ row }) => (
@@ -61,6 +31,84 @@ const useAttributesTableColumns = ({ selectedAttributes }: Props) => {
), ),
size: 5, size: 5,
}, },
{
header: "Название",
accessorKey: "label",
size: 150,
},
{
header: "Тип",
accessorKey: "type.name",
size: 120,
},
// {
// header: " ",
// Cell: ({ row }) => {
// const description = row.original.description ? `Описание: ${row.original.description}` : "";
// const info = (
// <Box>
// <Text>Может быть пустым: {row.original.isNullable ? "да" : "нет"}</Text>
// <Text>{defaultValueToStr(row.original.defaultValue, row.original.type.type)}</Text>
// <Text>Синхронизировано в группе: {row.original.isApplicableToGroup ? "да" : "нет"}</Text>
// <Text>{description}</Text>
// </Box>
// );
// return (
// <Tooltip label={info} multiline w={rem(300)}>
// <IconInfoCircle />
// </Tooltip>
// );
// },
// size: 5,
// },
{
header: "Значение по умолчанию",
accessorKey: "defaultValue",
Cell: ({ cell, row }) => {
const value = cell.getValue();
if (value === null) return <>-</>;
const type = row.original.type.type;
if (type === "datetime") {
return formatDateTime(value as string);
}
if (type === "date") {
return formatDate(value as string);
}
if (type === "bool") {
return value ? <IconCheck /> : <IconX />;
}
return <>{value}</>;
},
size: 150,
},
{
header: "Синхронизировано в группе",
accessorKey: "isApplicableToGroup",
Cell: ({ cell }) => cell.getValue() ? (
<IconCheck />
) : (
<IconX />
),
size: 120,
},
{
header: "Может быть пустым",
accessorKey: "isNullable",
Cell: ({ cell }) => cell.getValue() ? (
<IconCheck />
) : (
<IconX />
),
size: 120,
},
{
header: "Описаниие",
accessorKey: "description",
Cell: ({ row }) => <Box>{row.original.description}</Box>,
size: 250,
},
], ],
[selectedAttributes], [selectedAttributes],
); );

View File

@@ -11,11 +11,6 @@ type Props = {
const useModulesTableColumns = ({ selectedModules }: Props) => { const useModulesTableColumns = ({ selectedModules }: Props) => {
return useMemo<MRT_ColumnDef<ModuleSchema>[]>( return useMemo<MRT_ColumnDef<ModuleSchema>[]>(
() => [ () => [
{
header: "Название",
accessorKey: "label",
size: 25,
},
{ {
header: " ", header: " ",
Cell: ({ row }) => ( Cell: ({ row }) => (
@@ -32,7 +27,12 @@ const useModulesTableColumns = ({ selectedModules }: Props) => {
/> />
</Center> </Center>
), ),
size: 5, size: 1,
},
{
header: "Название",
accessorKey: "label",
size: 10000,
}, },
], ],
[selectedModules], [selectedModules],