From 76082b2a213116de299b8a033b11d47fcf1b5711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Gonz=C3=A1lez=20Mu=C3=B1oz?= Date: Wed, 22 Nov 2023 13:02:49 +0100 Subject: [PATCH] fixes menu action behaviour --- app/hooks/features/index.ts | 2 +- .../inventory-table/row-item/index.tsx | 24 +++++++++++++-- .../inventory-table/row-item/types.ts | 8 ++++- .../cost-surfaces/actions-menu/index.tsx | 30 +++++++++---------- .../features/actions-menu/index.tsx | 29 +++++++++++++----- .../inventory-panel/features/index.tsx | 2 +- .../wdpas/actions-menu/index.tsx | 29 +++++++++--------- 7 files changed, 81 insertions(+), 43 deletions(-) diff --git a/app/hooks/features/index.ts b/app/hooks/features/index.ts index 782326ba01..0352a542ab 100644 --- a/app/hooks/features/index.ts +++ b/app/hooks/features/index.ts @@ -277,7 +277,7 @@ export function useSelectedFeatures( max: amountMax, }, color: featureColorQueryState - ? featureColorQueryState.data.find(({ id }) => featureId === id)?.color + ? featureColorQueryState?.data?.find(({ id }) => featureId === id)?.color : null, // SPLIT diff --git a/app/layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item/index.tsx b/app/layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item/index.tsx index c1836a166f..ab4327f6d0 100644 --- a/app/layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item/index.tsx +++ b/app/layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item/index.tsx @@ -1,3 +1,5 @@ +import { useCallback, useRef, useState } from 'react'; + import { HiDotsHorizontal } from 'react-icons/hi'; import Checkbox from 'components/forms/checkbox'; @@ -18,6 +20,12 @@ const RowItem = ({ ActionsComponent, }: RowItem) => { const { id, name, scenarios, tag, isVisibleOnMap, isCustom } = item; + const [isMenuOpen, setIsMenuOpen] = useState(false); + const buttonRef = useRef(null); + + const onDismissMenu = useCallback(() => { + setIsMenuOpen(false); + }, []); return ( @@ -70,7 +78,7 @@ const RowItem = ({ /> - + { + if (evt.target !== buttonRef.current) { + setIsMenuOpen(false); + } + }} > - + diff --git a/app/layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item/types.ts b/app/layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item/types.ts index 5311d097a5..e077c5c856 100644 --- a/app/layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item/types.ts +++ b/app/layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item/types.ts @@ -7,5 +7,11 @@ export type RowItem = { selectedIds: string[]; onSelectRow: (evt: ChangeEvent) => void; onToggleSeeOnMap: (id: string) => void; - ActionsComponent: ({ item }: { item: DataItem }) => JSX.Element; + ActionsComponent: ({ + item, + onDismissMenu, + }: { + item: DataItem; + onDismissMenu: () => void; + }) => JSX.Element; }; diff --git a/app/layout/project/sidebar/project/inventory-panel/cost-surfaces/actions-menu/index.tsx b/app/layout/project/sidebar/project/inventory-panel/cost-surfaces/actions-menu/index.tsx index 8ac414a858..f706414172 100644 --- a/app/layout/project/sidebar/project/inventory-panel/cost-surfaces/actions-menu/index.tsx +++ b/app/layout/project/sidebar/project/inventory-panel/cost-surfaces/actions-menu/index.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState } from 'react'; +import { ComponentProps, useCallback, useState } from 'react'; import Icon from 'components/icon'; import Modal from 'components/modal/component'; @@ -9,6 +9,8 @@ import { cn } from 'utils/cn'; import DELETE_SVG from 'svgs/ui/new-layout/delete.svg?sprite'; import TAG_SVG from 'svgs/ui/tag.svg?sprite'; +import RowItem from '../../components/inventory-table/row-item'; + const BUTTON_CLASSES = 'flex items-center px-4 py-2 w-full text-sm cursor-pointer bg-gray-800 hover:bg-gray-600 transition transition-colors space-x-2 group'; @@ -16,26 +18,24 @@ const ICON_CLASSES = 'h-5 w-5 text-gray-100 group-hover:text-white'; const ActionsMenu = ({ item, -}: { - item: { - id: string; - name: string; - scenarios: number; - tag: string; - custom: boolean; - }; -}): JSX.Element => { - const isDeletable = !item.custom && !item.scenarios; + onDismissMenu, +}: Parameters['ActionsComponent']>[0]): JSX.Element => { + const isDeletable = !item.isCustom && !item.scenarios; - // item.isCustom && !item.scenarioUsageCount const [modalState, setModalState] = useState<{ edit: boolean; delete: boolean }>({ edit: false, delete: false, }); - const handleModal = useCallback((modalKey: keyof typeof modalState, isVisible: boolean) => { - setModalState((prevState) => ({ ...prevState, [modalKey]: isVisible })); - }, []); + const handleModal = useCallback( + (modalKey: keyof typeof modalState, isVisible: boolean) => { + setModalState((prevState) => { + if (!isVisible) onDismissMenu(); + return { ...prevState, [modalKey]: isVisible }; + }); + }, + [onDismissMenu] + ); return (
    diff --git a/app/layout/project/sidebar/project/inventory-panel/features/actions-menu/index.tsx b/app/layout/project/sidebar/project/inventory-panel/features/actions-menu/index.tsx index c27929aa94..28ceb13e1d 100644 --- a/app/layout/project/sidebar/project/inventory-panel/features/actions-menu/index.tsx +++ b/app/layout/project/sidebar/project/inventory-panel/features/actions-menu/index.tsx @@ -1,8 +1,8 @@ -import { useCallback, useState } from 'react'; +import { ComponentProps, useCallback, useState } from 'react'; import Icon from 'components/icon'; import Modal from 'components/modal/component'; -import { type DataItem } from 'layout/project/sidebar/project/inventory-panel/components/inventory-table'; +import RowItem from 'layout/project/sidebar/project/inventory-panel/components/inventory-table/row-item'; import DeleteModal from 'layout/project/sidebar/project/inventory-panel/features/modals/delete'; import EditModal from 'layout/project/sidebar/project/inventory-panel/features/modals/edit'; import { cn } from 'utils/cn'; @@ -19,7 +19,10 @@ const ICON_CLASSES = 'h-5 w-5 text-gray-100 group-hover:text-white'; const ICON_DISABLED_CLASSES = 'text-gray-700'; -const ActionsMenu = ({ item }: { item: DataItem }): JSX.Element => { +const ActionsMenu = ({ + item, + onDismissMenu, +}: Parameters['ActionsComponent']>[0]): JSX.Element => { const isDeletable = !item.isCustom || !item.scenarios; const [modalState, setModalState] = useState<{ edit: boolean; delete: boolean }>({ @@ -27,16 +30,24 @@ const ActionsMenu = ({ item }: { item: DataItem }): JSX.Element => { delete: false, }); - const handleModal = useCallback((modalKey: keyof typeof modalState, isVisible: boolean) => { - setModalState((prevState) => ({ ...prevState, [modalKey]: isVisible })); - }, []); + const handleModal = useCallback( + (modalKey: keyof typeof modalState, isVisible: boolean) => { + setModalState((prevState) => { + if (!isVisible) onDismissMenu(); + return { ...prevState, [modalKey]: isVisible }; + }); + }, + [onDismissMenu] + ); return (