feat: context menu for deal groups

This commit is contained in:
2025-10-18 00:33:12 +04:00
parent 5e59d54011
commit f90b335ee1
2 changed files with 22 additions and 51 deletions

View File

@ -1,9 +1,10 @@
import { FC, useEffect, useState } from "react"; import React, { FC, useEffect, useState } from "react";
import { IconCheckbox, IconTrash } from "@tabler/icons-react";
import classNames from "classnames"; import classNames from "classnames";
import { useContextMenu } from "mantine-contextmenu";
import { Flex, Stack, TextInput } from "@mantine/core"; import { Flex, Stack, TextInput } from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks"; import { useDebouncedValue } from "@mantine/hooks";
import DealCard from "@/app/deals/components/shared/DealCard/DealCard"; import DealCard from "@/app/deals/components/shared/DealCard/DealCard";
import GroupMenu from "@/app/deals/components/shared/GroupMenu/GroupMenu";
import { useDealsContext } from "@/app/deals/contexts/DealsContext"; import { useDealsContext } from "@/app/deals/contexts/DealsContext";
import GroupWithDealsSchema from "@/types/GroupWithDealsSchema"; import GroupWithDealsSchema from "@/types/GroupWithDealsSchema";
import styles from "./DealsGroup.module.css"; import styles from "./DealsGroup.module.css";
@ -16,12 +17,29 @@ const DealsGroup: FC<Props> = ({ group }) => {
const [groupName, setGroupName] = useState(group.name ?? ""); const [groupName, setGroupName] = useState(group.name ?? "");
const [debouncedGroupName] = useDebouncedValue(groupName, 600); const [debouncedGroupName] = useDebouncedValue(groupName, 600);
const { groupsCrud, groupDealsSelection } = useDealsContext(); const { groupsCrud, groupDealsSelection } = useDealsContext();
const { showContextMenu } = useContextMenu();
useEffect(() => { useEffect(() => {
if (debouncedGroupName === group.name) return; if (debouncedGroupName === group.name) return;
groupsCrud.onUpdate(group.id, { name: debouncedGroupName }); groupsCrud.onUpdate(group.id, { name: debouncedGroupName });
}, [debouncedGroupName]); }, [debouncedGroupName]);
const dealContextMenu = [
{
key: "delete",
onClick: () => groupsCrud.onDelete(group.id),
title: "Удалить группу",
icon: <IconTrash />,
},
{
key: "startDealsSelecting",
onClick: () =>
groupDealsSelection.startSelectingWithExistingGroup(group),
title: "Добавить/удалить сделки",
icon: <IconCheckbox />,
},
];
return ( return (
<Stack <Stack
className={classNames( className={classNames(
@ -31,7 +49,8 @@ const DealsGroup: FC<Props> = ({ group }) => {
)} )}
gap={"xs"} gap={"xs"}
bdrs={"lg"} bdrs={"lg"}
p={"xs"}> p={"xs"}
onContextMenu={showContextMenu(dealContextMenu)}>
<Flex <Flex
mx={"xs"} mx={"xs"}
align={"center"}> align={"center"}>
@ -41,13 +60,6 @@ const DealsGroup: FC<Props> = ({ group }) => {
variant={"unstyled"} variant={"unstyled"}
onKeyDown={e => e.stopPropagation()} onKeyDown={e => e.stopPropagation()}
/> />
<GroupMenu
group={group}
onDelete={groupsCrud.onDelete}
onStartDealsSelecting={
groupDealsSelection.startSelectingWithExistingGroup
}
/>
</Flex> </Flex>
{group.items.map(deal => ( {group.items.map(deal => (
<DealCard <DealCard

View File

@ -1,41 +0,0 @@
import React, { FC } from "react";
import { IconCheckbox, IconDotsVertical, IconTrash } from "@tabler/icons-react";
import { Box, Menu } from "@mantine/core";
import DropdownMenuItem from "@/components/ui/DropdownMenuItem/DropdownMenuItem";
import ThemeIcon from "@/components/ui/ThemeIcon/ThemeIcon";
import GroupWithDealsSchema from "@/types/GroupWithDealsSchema";
type Props = {
group: GroupWithDealsSchema;
onDelete: (groupId: number) => void;
onStartDealsSelecting: (group: GroupWithDealsSchema) => void;
};
const GroupMenu: FC<Props> = ({ group, onDelete, onStartDealsSelecting }) => {
return (
<Menu>
<Menu.Target>
<Box onClick={e => e.stopPropagation()}>
<ThemeIcon size={"sm"}>
<IconDotsVertical />
</ThemeIcon>
</Box>
</Menu.Target>
<Menu.Dropdown>
<DropdownMenuItem
onClick={() => onDelete(group.id)}
icon={<IconTrash />}
label={"Удалить"}
/>
<DropdownMenuItem
onClick={() => onStartDealsSelecting(group)}
icon={<IconCheckbox />}
label={"Добавить/удалить сделки"}
/>
</Menu.Dropdown>
</Menu>
);
};
export default GroupMenu;