feat: context menu for deal groups
This commit is contained in:
@ -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
|
||||||
|
|||||||
@ -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;
|
|
||||||
Reference in New Issue
Block a user