feat: modules page and module editor page for mobiles
This commit is contained in:
@ -0,0 +1,40 @@
|
||||
"use client";
|
||||
|
||||
import { FC, useMemo } from "react";
|
||||
import useAttributesList from "@/app/module-editor/[moduleId]/hooks/useAttributesList";
|
||||
import ObjectSelect, {
|
||||
ObjectSelectProps,
|
||||
} from "@/components/selects/ObjectSelect/ObjectSelect";
|
||||
import { AttributeSchema } from "@/lib/client";
|
||||
|
||||
type Props = Omit<
|
||||
ObjectSelectProps<AttributeSchema | null>,
|
||||
"data" | "getLabelFn" | "getValueFn"
|
||||
> & {
|
||||
attributesToExclude?: AttributeSchema[];
|
||||
};
|
||||
|
||||
const AttributeSelect: FC<Props> = ({ attributesToExclude, ...props }) => {
|
||||
const { attributes } = useAttributesList();
|
||||
|
||||
const availableAttributes = useMemo(() => {
|
||||
const attrIdsToExcludeSet = new Set(
|
||||
attributesToExclude?.map(a => a.id)
|
||||
);
|
||||
|
||||
return attributes.filter(a => !attrIdsToExcludeSet.has(a.id));
|
||||
}, [attributes, attributesToExclude]);
|
||||
|
||||
return (
|
||||
<ObjectSelect
|
||||
searchable
|
||||
placeholder={"Выберите статус"}
|
||||
onClear={() => props.onChange(null)}
|
||||
getLabelFn={(option: AttributeSchema) => option.label}
|
||||
data={availableAttributes}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default AttributeSelect;
|
||||
@ -24,7 +24,7 @@ const useAttributesTableColumns = () => {
|
||||
accessor: "type.name",
|
||||
render: attr =>
|
||||
attr.type.type === "select"
|
||||
? `Выбор "${attr.select?.label}"`
|
||||
? `Выбор "${attr.select?.name}"`
|
||||
: attr.type.name,
|
||||
},
|
||||
{
|
||||
|
||||
@ -42,7 +42,7 @@ const ModuleAttribute: FC<Props> = ({ attribute }) => {
|
||||
<>{getAttrLabelText()}</>
|
||||
<Text>
|
||||
Тип: {attribute.type.name}{" "}
|
||||
{attribute.select && `"${attribute.select.label}"`}
|
||||
{attribute.select && `"${attribute.select.name}"`}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Group
|
||||
|
||||
@ -1,11 +1,18 @@
|
||||
import React, { ReactNode } from "react";
|
||||
import { Flex } from "@mantine/core";
|
||||
import { modals } from "@mantine/modals";
|
||||
import ModuleAttribute from "@/app/module-editor/[moduleId]/components/shared/ModuleAttribute/ModuleAttribute";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import FormFlexRow from "@/components/ui/FormFlexRow/FormFlexRow";
|
||||
import InlineButton from "@/components/ui/InlineButton/InlineButton";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
|
||||
const ModuleAttributesEditor = () => {
|
||||
const { module } = useModuleEditorContext();
|
||||
const {
|
||||
module,
|
||||
attributeActions: { addAttributeToModule },
|
||||
} = useModuleEditorContext();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const getAttributesRows = () => {
|
||||
if (!module?.attributes) return [];
|
||||
@ -29,10 +36,27 @@ const ModuleAttributesEditor = () => {
|
||||
return rows;
|
||||
};
|
||||
|
||||
const onAddAttributeClick = () => {
|
||||
modals.openContextModal({
|
||||
modal: "addAttributeModal",
|
||||
title: "Добавление атрибута",
|
||||
withCloseButton: true,
|
||||
innerProps: {
|
||||
onSubmit: addAttributeToModule,
|
||||
usedAttributes: module?.attributes ?? [],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex
|
||||
gap={"xs"}
|
||||
gap={isMobile ? "md" : "xs"}
|
||||
direction={"column"}>
|
||||
{isMobile && (
|
||||
<InlineButton onClick={onAddAttributeClick}>
|
||||
Добавить атрибут
|
||||
</InlineButton>
|
||||
)}
|
||||
{getAttributesRows()}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Button, Flex, Group, Textarea, TextInput } from "@mantine/core";
|
||||
import { useForm } from "@mantine/form";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
import { ModuleInfo } from "../../../hooks/useModulesActions";
|
||||
|
||||
const ModuleCommonInfoEditor = () => {
|
||||
@ -8,6 +9,7 @@ const ModuleCommonInfoEditor = () => {
|
||||
module,
|
||||
moduleActions: { updateCommonInfo },
|
||||
} = useModuleEditorContext();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const form = useForm<ModuleInfo>({
|
||||
initialValues: module ?? {
|
||||
@ -39,6 +41,7 @@ const ModuleCommonInfoEditor = () => {
|
||||
<Group>
|
||||
<Button
|
||||
variant={"default"}
|
||||
w={isMobile ? "100%" : "auto"}
|
||||
disabled={!form.isDirty()}
|
||||
type={"submit"}>
|
||||
Сохранить
|
||||
|
||||
@ -7,52 +7,77 @@ import ModuleAttributesEditor from "@/app/module-editor/[moduleId]/components/sh
|
||||
import ModuleCommonInfoEditor from "@/app/module-editor/[moduleId]/components/shared/ModuleCommonInfoEditor/ModuleCommonInfoEditor";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
|
||||
const PageBody = () => {
|
||||
const { module } = useModuleEditorContext();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
if (!module) return;
|
||||
|
||||
const renderMobile = () => (
|
||||
<Flex
|
||||
m={"xs"}
|
||||
gap={"xs"}
|
||||
flex={2}
|
||||
direction={"column"}>
|
||||
<Fieldset
|
||||
flex={1}
|
||||
legend={"Общие данные модуля"}>
|
||||
{module && <ModuleCommonInfoEditor />}
|
||||
</Fieldset>
|
||||
<Fieldset
|
||||
flex={3}
|
||||
legend={"Атрибуты модуля"}>
|
||||
<ModuleAttributesEditor />
|
||||
</Fieldset>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
const renderDesktop = () => (
|
||||
<Flex
|
||||
w={"100%"}
|
||||
h={"100%"}
|
||||
flex={3}
|
||||
style={{ overflow: "auto" }}
|
||||
gap={"md"}>
|
||||
<Fieldset
|
||||
flex={1}
|
||||
legend={"Атрибуты"}>
|
||||
<Flex
|
||||
direction={"column"}
|
||||
h={"100%"}
|
||||
gap={"xs"}>
|
||||
<Box style={{ flex: 1, minHeight: 0 }}>
|
||||
<AttributesTable />
|
||||
</Box>
|
||||
<CreateAttributeButton />
|
||||
</Flex>
|
||||
</Fieldset>
|
||||
<Flex
|
||||
gap={"xs"}
|
||||
flex={2}
|
||||
direction={"column"}>
|
||||
<Fieldset
|
||||
flex={1}
|
||||
legend={"Общие данные модуля"}>
|
||||
{module && <ModuleCommonInfoEditor />}
|
||||
</Fieldset>
|
||||
<Fieldset
|
||||
flex={3}
|
||||
legend={"Атрибуты модуля"}>
|
||||
<ModuleAttributesEditor />
|
||||
</Fieldset>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
return (
|
||||
<Stack h={"100%"}>
|
||||
<PageBlock
|
||||
style={{ flex: 1, minHeight: 0 }}
|
||||
fullScreenMobile>
|
||||
<Flex
|
||||
w={"100%"}
|
||||
h={"100%"}
|
||||
flex={3}
|
||||
style={{ overflow: "auto" }}
|
||||
gap={"md"}>
|
||||
<Fieldset
|
||||
flex={1}
|
||||
legend={"Атрибуты"}>
|
||||
<Flex
|
||||
direction={"column"}
|
||||
h={"100%"}
|
||||
gap={"xs"}>
|
||||
<Box style={{ flex: 1, minHeight: 0 }}>
|
||||
<AttributesTable />
|
||||
</Box>
|
||||
<CreateAttributeButton />
|
||||
</Flex>
|
||||
</Fieldset>
|
||||
<Flex
|
||||
gap={"xs"}
|
||||
flex={2}
|
||||
direction={"column"}>
|
||||
<Fieldset
|
||||
flex={1}
|
||||
legend={"Общие данные модуля"}>
|
||||
{module && <ModuleCommonInfoEditor />}
|
||||
</Fieldset>
|
||||
<Fieldset
|
||||
flex={3}
|
||||
legend={"Атрибуты модуля"}>
|
||||
<ModuleAttributesEditor />
|
||||
</Fieldset>
|
||||
</Flex>
|
||||
</Flex>
|
||||
{isMobile ? renderMobile() : renderDesktop()}
|
||||
</PageBlock>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user