refactor: filters modal with context
This commit is contained in:
@ -8,7 +8,7 @@ import ToolPanelAction from "@/app/deals/components/desktop/ToolPanelAction/Tool
|
|||||||
import ViewSelector from "@/app/deals/components/desktop/ViewSelector/ViewSelector";
|
import ViewSelector from "@/app/deals/components/desktop/ViewSelector/ViewSelector";
|
||||||
import { useDealsContext } from "@/app/deals/contexts/DealsContext";
|
import { useDealsContext } from "@/app/deals/contexts/DealsContext";
|
||||||
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext";
|
||||||
import DealsTableFiltersModal from "@/app/deals/modals/DealsTableFiltersModal/DealsTableFiltersModal";
|
import { DealsFiltersForm } from "@/app/deals/hooks/useDealsFilters";
|
||||||
import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect";
|
import ProjectSelect from "@/components/selects/ProjectSelect/ProjectSelect";
|
||||||
import { useDrawersContext } from "@/drawers/DrawersContext";
|
import { useDrawersContext } from "@/drawers/DrawersContext";
|
||||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||||
@ -49,6 +49,21 @@ const TopToolPanel: FC<Props> = ({ view, setView }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onFiltersClick = () => {
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "dealsFiltersModal",
|
||||||
|
title: "Фильтры",
|
||||||
|
withCloseButton: true,
|
||||||
|
innerProps: {
|
||||||
|
value: dealsFiltersForm.values,
|
||||||
|
onChange: (values: DealsFiltersForm) =>
|
||||||
|
dealsFiltersForm.setValues(values),
|
||||||
|
project: selectedProject,
|
||||||
|
boardAndStatusEnabled: view === "table",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group justify={"space-between"}>
|
<Group justify={"space-between"}>
|
||||||
<ViewSelector
|
<ViewSelector
|
||||||
@ -59,8 +74,6 @@ const TopToolPanel: FC<Props> = ({ view, setView }) => {
|
|||||||
wrap={"nowrap"}
|
wrap={"nowrap"}
|
||||||
align={"center"}
|
align={"center"}
|
||||||
gap={"sm"}>
|
gap={"sm"}>
|
||||||
<DealsTableFiltersModal
|
|
||||||
getOpener={onFiltersClick => (
|
|
||||||
<Indicator
|
<Indicator
|
||||||
zIndex={100}
|
zIndex={100}
|
||||||
disabled={!isChangedFilters}
|
disabled={!isChangedFilters}
|
||||||
@ -70,11 +83,6 @@ const TopToolPanel: FC<Props> = ({ view, setView }) => {
|
|||||||
<IconFilter />
|
<IconFilter />
|
||||||
</ToolPanelAction>
|
</ToolPanelAction>
|
||||||
</Indicator>
|
</Indicator>
|
||||||
)}
|
|
||||||
filtersForm={dealsFiltersForm}
|
|
||||||
selectedProject={selectedProject}
|
|
||||||
boardAndStatusEnabled={view === "table"}
|
|
||||||
/>
|
|
||||||
<ToolPanelAction onClick={onEditClick}>
|
<ToolPanelAction onClick={onEditClick}>
|
||||||
<IconEdit />
|
<IconEdit />
|
||||||
</ToolPanelAction>
|
</ToolPanelAction>
|
||||||
|
|||||||
91
src/app/deals/modals/DealsFiltersModal/DealsFiltersModal.tsx
Normal file
91
src/app/deals/modals/DealsFiltersModal/DealsFiltersModal.tsx
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
NumberInput,
|
||||||
|
rem,
|
||||||
|
Space,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { useForm } from "@mantine/form";
|
||||||
|
import { ContextModalProps } from "@mantine/modals";
|
||||||
|
import { DealsFiltersForm } from "@/app/deals/hooks/useDealsFilters";
|
||||||
|
import BoardSelect from "@/components/selects/BoardSelect/BoardSelect";
|
||||||
|
import StatusSelect from "@/components/selects/StatusSelect/StatusSelect";
|
||||||
|
import { ProjectSchema } from "@/lib/client";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
value: DealsFiltersForm;
|
||||||
|
onChange: (values: DealsFiltersForm) => void;
|
||||||
|
project: ProjectSchema | null;
|
||||||
|
boardAndStatusEnabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DealsFiltersModal = ({
|
||||||
|
id,
|
||||||
|
context,
|
||||||
|
innerProps,
|
||||||
|
}: ContextModalProps<Props>) => {
|
||||||
|
const filtersForm = useForm({
|
||||||
|
initialValues: innerProps.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = (values: DealsFiltersForm) => {
|
||||||
|
innerProps.onChange(values);
|
||||||
|
context.closeModal(id);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={filtersForm.onSubmit(onSubmit)}>
|
||||||
|
<Flex
|
||||||
|
gap={rem(10)}
|
||||||
|
direction={"column"}>
|
||||||
|
<NumberInput
|
||||||
|
label={"ID"}
|
||||||
|
placeholder={"Введите ID"}
|
||||||
|
{...filtersForm.getInputProps("id")}
|
||||||
|
value={filtersForm.values.id ?? ""}
|
||||||
|
onChange={value =>
|
||||||
|
typeof value === "number"
|
||||||
|
? filtersForm.setFieldValue("id", Number(value))
|
||||||
|
: filtersForm.setFieldValue("id", null)
|
||||||
|
}
|
||||||
|
hideControls
|
||||||
|
min={1}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
label={"Название"}
|
||||||
|
placeholder={"Введите название"}
|
||||||
|
{...filtersForm.getInputProps("name")}
|
||||||
|
/>
|
||||||
|
{innerProps.boardAndStatusEnabled && (
|
||||||
|
<>
|
||||||
|
<BoardSelect
|
||||||
|
label={"Доска"}
|
||||||
|
{...filtersForm.getInputProps("board")}
|
||||||
|
projectId={innerProps.project?.id}
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
<StatusSelect
|
||||||
|
label={"Статус"}
|
||||||
|
{...filtersForm.getInputProps("status")}
|
||||||
|
boardId={filtersForm.values.board?.id}
|
||||||
|
clearable
|
||||||
|
clearOnBoardChange
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<Space />
|
||||||
|
<Button
|
||||||
|
variant={"default"}
|
||||||
|
type={"submit"}>
|
||||||
|
<Text>Сохранить</Text>
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DealsFiltersModal;
|
||||||
@ -1,78 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { ReactNode } from "react";
|
|
||||||
import { Flex, Modal, NumberInput, rem, TextInput } from "@mantine/core";
|
|
||||||
import { UseFormReturnType } from "@mantine/form";
|
|
||||||
import { useDisclosure } from "@mantine/hooks";
|
|
||||||
import { DealsFiltersForm } from "@/app/deals/hooks/useDealsFilters";
|
|
||||||
import BoardSelect from "@/components/selects/BoardSelect/BoardSelect";
|
|
||||||
import StatusSelect from "@/components/selects/StatusSelect/StatusSelect";
|
|
||||||
import { ProjectSchema } from "@/lib/client";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
filtersForm: UseFormReturnType<DealsFiltersForm>;
|
|
||||||
selectedProject: ProjectSchema | null;
|
|
||||||
boardAndStatusEnabled: boolean;
|
|
||||||
getOpener: (open: () => void) => ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
const DealsTableFiltersModal = ({
|
|
||||||
filtersForm,
|
|
||||||
selectedProject,
|
|
||||||
boardAndStatusEnabled,
|
|
||||||
getOpener,
|
|
||||||
}: Props) => {
|
|
||||||
const [opened, { open, close }] = useDisclosure();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{getOpener(open)}
|
|
||||||
<Modal
|
|
||||||
title={"Фильтры"}
|
|
||||||
opened={opened}
|
|
||||||
onClose={close}>
|
|
||||||
<Flex
|
|
||||||
gap={rem(10)}
|
|
||||||
direction={"column"}>
|
|
||||||
<NumberInput
|
|
||||||
label={"ID"}
|
|
||||||
placeholder={"Введите ID"}
|
|
||||||
{...filtersForm.getInputProps("id")}
|
|
||||||
value={filtersForm.values.id ?? ""}
|
|
||||||
onChange={value =>
|
|
||||||
typeof value === "number"
|
|
||||||
? filtersForm.setFieldValue("id", Number(value))
|
|
||||||
: filtersForm.setFieldValue("id", null)
|
|
||||||
}
|
|
||||||
hideControls
|
|
||||||
min={1}
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
label={"Название"}
|
|
||||||
placeholder={"Введите название"}
|
|
||||||
{...filtersForm.getInputProps("name")}
|
|
||||||
/>
|
|
||||||
{boardAndStatusEnabled && (
|
|
||||||
<>
|
|
||||||
<BoardSelect
|
|
||||||
label={"Доска"}
|
|
||||||
{...filtersForm.getInputProps("board")}
|
|
||||||
projectId={selectedProject?.id}
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
<StatusSelect
|
|
||||||
label={"Статус"}
|
|
||||||
{...filtersForm.getInputProps("status")}
|
|
||||||
boardId={filtersForm.values.board?.id}
|
|
||||||
clearable
|
|
||||||
clearOnBoardChange
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DealsTableFiltersModal;
|
|
||||||
@ -1,5 +1,7 @@
|
|||||||
|
import DealsFiltersModal from "@/app/deals/modals/DealsFiltersModal/DealsFiltersModal";
|
||||||
import EnterNameModal from "@/modals/EnterNameModal/EnterNameModal";
|
import EnterNameModal from "@/modals/EnterNameModal/EnterNameModal";
|
||||||
|
|
||||||
export const modals = {
|
export const modals = {
|
||||||
enterNameModal: EnterNameModal,
|
enterNameModal: EnterNameModal,
|
||||||
|
dealsFiltersModal: DealsFiltersModal,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user