Files
twenty/front/src/modules/ui/board/components/BoardColumnMenu.tsx
gitstart-twenty 00a3c8ca2b Change to using arrow functions (#1603)
* Change to using arrow functions

Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>

* Add lint rule

---------

Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2023-09-15 18:41:10 -07:00

172 lines
5.3 KiB
TypeScript

import { useCallback, useRef, useState } from 'react';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
import { useCreateCompanyProgress } from '@/companies/hooks/useCreateCompanyProgress';
import { useFilteredSearchCompanyQuery } from '@/companies/hooks/useFilteredSearchCompanyQuery';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { IconPencil, IconPlus, IconTrash } from '@/ui/icon';
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar';
import { ThemeColor } from '@/ui/theme/constants/colors';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { boardColumnsState } from '../states/boardColumnsState';
import { BoardColumnHotkeyScope } from '../types/BoardColumnHotkeyScope';
import { BoardColumnEditTitleMenu } from './BoardColumnEditTitleMenu';
const StyledMenuContainer = styled.div`
position: absolute;
width: 200px;
z-index: 1;
`;
type OwnProps = {
color: ThemeColor;
onClose: () => void;
onDelete?: (id: string) => void;
onTitleEdit: (title: string, color: string) => void;
stageId: string;
title: string;
};
type Menu = 'actions' | 'add' | 'title';
export const BoardColumnMenu = ({
color,
onClose,
onDelete,
onTitleEdit,
stageId,
title,
}: OwnProps) => {
const [currentMenu, setCurrentMenu] = useState('actions');
const [, setBoardColumns] = useRecoilState(boardColumnsState);
const boardColumnMenuRef = useRef(null);
const { enqueueSnackBar } = useSnackBar();
const createCompanyProgress = useCreateCompanyProgress();
const handleCompanySelected = (
selectedCompany: EntityForSelect | null | undefined,
) => {
if (!selectedCompany?.id) {
enqueueSnackBar(
'There was a problem with the company selection, please retry.',
{
variant: 'error',
},
);
console.error(
'There was a problem with the company selection, please retry.',
);
return;
}
createCompanyProgress(selectedCompany.id, stageId);
closeMenu();
};
const {
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope();
const closeMenu = useCallback(() => {
goBackToPreviousHotkeyScope();
onClose();
}, [goBackToPreviousHotkeyScope, onClose]);
const handleDelete = useCallback(() => {
setBoardColumns((previousBoardColumns) =>
previousBoardColumns.filter((column) => column.id !== stageId),
);
onDelete?.(stageId);
closeMenu();
}, [closeMenu, onDelete, setBoardColumns, stageId]);
const setMenu = (menu: Menu) => {
if (menu === 'add') {
setHotkeyScopeAndMemorizePreviousScope(
RelationPickerHotkeyScope.RelationPicker,
);
}
setCurrentMenu(menu);
};
const [relationPickerSearchFilter] = useRecoilScopedState(
relationPickerSearchFilterScopedState,
);
const companies = useFilteredSearchCompanyQuery({
searchFilter: relationPickerSearchFilter,
});
useListenClickOutside({
refs: [boardColumnMenuRef],
callback: closeMenu,
});
useScopedHotkeys(
[Key.Escape, Key.Enter],
closeMenu,
BoardColumnHotkeyScope.BoardColumn,
[],
);
return (
<StyledMenuContainer ref={boardColumnMenuRef}>
<StyledDropdownMenu>
{currentMenu === 'actions' && (
<StyledDropdownMenuItemsContainer>
<MenuItem
onClick={() => setMenu('title')}
LeftIcon={IconPencil}
text="Rename"
/>
<MenuItem
onClick={handleDelete}
LeftIcon={IconTrash}
text="Delete"
/>
<MenuItem
onClick={() => setMenu('add')}
LeftIcon={IconPlus}
text="New opportunity"
/>
</StyledDropdownMenuItemsContainer>
)}
{currentMenu === 'title' && (
<BoardColumnEditTitleMenu
color={color}
onClose={closeMenu}
onTitleEdit={onTitleEdit}
title={title}
/>
)}
{currentMenu === 'add' && (
<SingleEntitySelect
disableBackgroundBlur
entitiesToSelect={companies.entitiesToSelect}
loading={companies.loading}
onCancel={closeMenu}
onEntitySelected={handleCompanySelected}
selectedEntity={companies.selectedEntities[0]}
/>
)}
</StyledDropdownMenu>
</StyledMenuContainer>
);
};