diff --git a/front/src/modules/companies/components/HooksCompanyBoard.tsx b/front/src/modules/companies/components/HooksCompanyBoard.tsx index 98cac7f3f..5a6654c4e 100644 --- a/front/src/modules/companies/components/HooksCompanyBoard.tsx +++ b/front/src/modules/companies/components/HooksCompanyBoard.tsx @@ -3,6 +3,7 @@ import { useRecoilState, useSetRecoilState } from 'recoil'; import { pipelineViewFields } from '@/pipeline/constants/pipelineViewFields'; import { useBoardActionBarEntries } from '@/ui/board/hooks/useBoardActionBarEntries'; +import { useBoardContextMenuEntries } from '@/ui/board/hooks/useBoardContextMenuEntries'; import { isBoardLoadedState } from '@/ui/board/states/isBoardLoadedState'; import { viewFieldsDefinitionsState } from '@/ui/board/states/viewFieldsDefinitionsState'; import { availableFiltersScopedState } from '@/ui/filter-n-sort/states/availableFiltersScopedState'; @@ -117,10 +118,12 @@ export function HooksCompanyBoard({ loadingGetPipelines || loadingGetPipelineProgress || loadingGetCompanies; const { setActionBarEntries } = useBoardActionBarEntries(); + const { setContextMenuEntries } = useBoardContextMenuEntries(); useEffect(() => { if (!loading && pipeline && pipelineProgresses && companiesData) { setActionBarEntries(); + setContextMenuEntries(); updateCompanyBoard(pipeline, pipelineProgresses, companiesData.companies); } }, [ @@ -130,6 +133,7 @@ export function HooksCompanyBoard({ companiesData, updateCompanyBoard, setActionBarEntries, + setContextMenuEntries, ]); return <>; diff --git a/front/src/modules/ui/board/components/EntityBoardCard.tsx b/front/src/modules/ui/board/components/EntityBoardCard.tsx index 764826328..dadd88f88 100644 --- a/front/src/modules/ui/board/components/EntityBoardCard.tsx +++ b/front/src/modules/ui/board/components/EntityBoardCard.tsx @@ -1,5 +1,10 @@ import { Draggable } from '@hello-pangea/dnd'; +import { useSetRecoilState } from 'recoil'; +import { contextMenuIsOpenState } from '@/ui/context-menu/states/contextMenuIsOpenState'; +import { contextMenuPositionState } from '@/ui/context-menu/states/contextMenuPositionState'; + +import { useCurrentCardSelected } from '../hooks/useCurrentCardSelected'; import { BoardOptions } from '../types/BoardOptions'; export function EntityBoardCard({ @@ -11,6 +16,21 @@ export function EntityBoardCard({ cardId: string; index: number; }) { + const setContextMenuPosition = useSetRecoilState(contextMenuPositionState); + const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); + + const { setCurrentCardSelected } = useCurrentCardSelected(); + + function handleContextMenu(event: React.MouseEvent) { + event.preventDefault(); + setCurrentCardSelected(true); + setContextMenuPosition({ + x: event.clientX, + y: event.clientY, + }); + setContextMenuOpenState(true); + } + return ( {(draggableProvided) => ( @@ -20,6 +40,7 @@ export function EntityBoardCard({ {...draggableProvided?.draggableProps} data-selectable-id={cardId} data-select-disable + onContextMenu={handleContextMenu} > {boardOptions.cardComponent} diff --git a/front/src/modules/ui/board/components/EntityBoardContextMenu.tsx b/front/src/modules/ui/board/components/EntityBoardContextMenu.tsx new file mode 100644 index 000000000..a0b582170 --- /dev/null +++ b/front/src/modules/ui/board/components/EntityBoardContextMenu.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { useRecoilValue } from 'recoil'; + +import { ContextMenu } from '@/ui/context-menu/components/ContextMenu'; + +import { selectedCardIdsSelector } from '../states/selectors/selectedCardIdsSelector'; + +export function EntityBoardContextMenu() { + const selectedBoardCards = useRecoilValue(selectedCardIdsSelector); + return ; +} diff --git a/front/src/modules/ui/board/hooks/useBoardActionBarEntries.tsx b/front/src/modules/ui/board/hooks/useBoardActionBarEntries.tsx index 9a0bea2c4..b0f27784f 100644 --- a/front/src/modules/ui/board/hooks/useBoardActionBarEntries.tsx +++ b/front/src/modules/ui/board/hooks/useBoardActionBarEntries.tsx @@ -1,16 +1,26 @@ import { useSetRecoilState } from 'recoil'; +import { ActionBarEntry } from '@/ui/action-bar/components/ActionBarEntry'; import { actionBarEntriesState } from '@/ui/action-bar/states/actionBarEntriesState'; +import { IconTrash } from '@/ui/icon'; -import { BoardActionBarButtonDeleteBoardCard } from '../components/BoardActionBarButtonDeleteBoardCard'; +import { useDeleteSelectedBoardCards } from './useDeleteSelectedBoardCards'; export function useBoardActionBarEntries() { const setActionBarEntries = useSetRecoilState(actionBarEntriesState); + const deleteSelectedBoardCards = useDeleteSelectedBoardCards(); + return { setActionBarEntries: () => setActionBarEntries([ - , + } + type="danger" + onClick={deleteSelectedBoardCards} + key="delete" + />, ]), }; } diff --git a/front/src/modules/ui/board/hooks/useBoardContextMenuEntries.tsx b/front/src/modules/ui/board/hooks/useBoardContextMenuEntries.tsx new file mode 100644 index 000000000..95aad392b --- /dev/null +++ b/front/src/modules/ui/board/hooks/useBoardContextMenuEntries.tsx @@ -0,0 +1,26 @@ +import { IconTrash } from '@tabler/icons-react'; +import { useSetRecoilState } from 'recoil'; + +import { ContextMenuEntry } from '@/ui/context-menu/components/ContextMenuEntry'; +import { contextMenuEntriesState } from '@/ui/context-menu/states/contextMenuEntriesState'; + +import { useDeleteSelectedBoardCards } from './useDeleteSelectedBoardCards'; + +export function useBoardContextMenuEntries() { + const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState); + + const deleteSelectedBoardCards = useDeleteSelectedBoardCards(); + + return { + setContextMenuEntries: () => + setContextMenuEntries([ + } + accent="danger" + onClick={() => deleteSelectedBoardCards()} + key="delete" + />, + ]), + }; +} diff --git a/front/src/modules/ui/board/components/BoardActionBarButtonDeleteBoardCard.tsx b/front/src/modules/ui/board/hooks/useDeleteSelectedBoardCards.ts similarity index 70% rename from front/src/modules/ui/board/components/BoardActionBarButtonDeleteBoardCard.tsx rename to front/src/modules/ui/board/hooks/useDeleteSelectedBoardCards.ts index 45e19ac45..e1a82ca1b 100644 --- a/front/src/modules/ui/board/components/BoardActionBarButtonDeleteBoardCard.tsx +++ b/front/src/modules/ui/board/hooks/useDeleteSelectedBoardCards.ts @@ -2,14 +2,13 @@ import { getOperationName } from '@apollo/client/utilities'; import { useRecoilValue } from 'recoil'; import { GET_PIPELINES } from '@/pipeline/graphql/queries/getPipelines'; -import { ActionBarEntry } from '@/ui/action-bar/components/ActionBarEntry'; -import { IconTrash } from '@/ui/icon/index'; import { useDeleteManyPipelineProgressMutation } from '~/generated/graphql'; -import { useRemoveCardIds } from '../hooks/useRemoveCardIds'; import { selectedCardIdsSelector } from '../states/selectors/selectedCardIdsSelector'; -export function BoardActionBarButtonDeleteBoardCard() { +import { useRemoveCardIds } from './useRemoveCardIds'; + +export function useDeleteSelectedBoardCards() { const selectedCardIds = useRecoilValue(selectedCardIdsSelector); const removeCardIds = useRemoveCardIds(); @@ -17,7 +16,7 @@ export function BoardActionBarButtonDeleteBoardCard() { refetchQueries: [getOperationName(GET_PIPELINES) ?? ''], }); - async function handleDelete() { + async function deleteSelectedBoardCards() { await deletePipelineProgress({ variables: { ids: selectedCardIds, @@ -37,13 +36,5 @@ export function BoardActionBarButtonDeleteBoardCard() { }); } - return ( - } - type="danger" - onClick={handleDelete} - key="delete" - /> - ); + return deleteSelectedBoardCards; } diff --git a/front/src/pages/opportunities/Opportunities.tsx b/front/src/pages/opportunities/Opportunities.tsx index f40704b8d..ec73d7719 100644 --- a/front/src/pages/opportunities/Opportunities.tsx +++ b/front/src/pages/opportunities/Opportunities.tsx @@ -5,6 +5,7 @@ import { HooksCompanyBoard } from '@/companies/components/HooksCompanyBoard'; import { CompanyBoardRecoilScopeContext } from '@/companies/states/recoil-scope-contexts/CompanyBoardRecoilScopeContext'; import { EntityBoard } from '@/ui/board/components/EntityBoard'; import { EntityBoardActionBar } from '@/ui/board/components/EntityBoardActionBar'; +import { EntityBoardContextMenu } from '@/ui/board/components/EntityBoardContextMenu'; import { BoardOptionsContext } from '@/ui/board/contexts/BoardOptionsContext'; import { reduceSortsToOrderBy } from '@/ui/filter-n-sort/helpers'; import { SelectedSortType } from '@/ui/filter-n-sort/types/interface'; @@ -76,6 +77,7 @@ export function Opportunities() { onEditColumnTitle={handleEditColumnTitle} /> +