Create opportunity from board column menu (#1323)
- create opportunity from column menu
This commit is contained in:
@ -59,6 +59,7 @@ export type BoardColumnProps = {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
isFirstColumn: boolean;
|
isFirstColumn: boolean;
|
||||||
numChildren: number;
|
numChildren: number;
|
||||||
|
stageId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function BoardColumn({
|
export function BoardColumn({
|
||||||
@ -69,6 +70,7 @@ export function BoardColumn({
|
|||||||
children,
|
children,
|
||||||
isFirstColumn,
|
isFirstColumn,
|
||||||
numChildren,
|
numChildren,
|
||||||
|
stageId,
|
||||||
}: BoardColumnProps) {
|
}: BoardColumnProps) {
|
||||||
const [isBoardColumnMenuOpen, setIsBoardColumnMenuOpen] =
|
const [isBoardColumnMenuOpen, setIsBoardColumnMenuOpen] =
|
||||||
React.useState(false);
|
React.useState(false);
|
||||||
@ -103,6 +105,7 @@ export function BoardColumn({
|
|||||||
onTitleEdit={onTitleEdit}
|
onTitleEdit={onTitleEdit}
|
||||||
title={title}
|
title={title}
|
||||||
color={color}
|
color={color}
|
||||||
|
stageId={stageId}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -1,14 +1,23 @@
|
|||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { IconPencil } from '@tabler/icons-react';
|
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
|
import { useCreateCompanyProgress } from '@/companies/hooks/useCreateCompanyProgress';
|
||||||
|
import { useFilteredSearchCompanyQuery } from '@/companies/hooks/useFilteredSearchCompanyQuery';
|
||||||
import { DropdownMenuSelectableItem } from '@/ui/dropdown/components/DropdownMenuSelectableItem';
|
import { DropdownMenuSelectableItem } from '@/ui/dropdown/components/DropdownMenuSelectableItem';
|
||||||
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
|
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
|
||||||
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
|
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
|
||||||
|
import { IconPencil, IconPlus } 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 { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar';
|
||||||
import { icon } from '@/ui/theme/constants/icon';
|
import { icon } from '@/ui/theme/constants/icon';
|
||||||
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
|
||||||
import { BoardColumnHotkeyScope } from '../types/BoardColumnHotkeyScope';
|
import { BoardColumnHotkeyScope } from '../types/BoardColumnHotkeyScope';
|
||||||
|
|
||||||
@ -25,6 +34,7 @@ type OwnProps = {
|
|||||||
title: string;
|
title: string;
|
||||||
color: string;
|
color: string;
|
||||||
onTitleEdit: (title: string, color: string) => void;
|
onTitleEdit: (title: string, color: string) => void;
|
||||||
|
stageId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function BoardColumnMenu({
|
export function BoardColumnMenu({
|
||||||
@ -32,18 +42,65 @@ export function BoardColumnMenu({
|
|||||||
onTitleEdit,
|
onTitleEdit,
|
||||||
title,
|
title,
|
||||||
color,
|
color,
|
||||||
|
stageId,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
const [openMenu, setOpenMenu] = useState('actions');
|
const [openMenu, setOpenMenu] = useState('actions');
|
||||||
const boardColumnMenuRef = useRef(null);
|
const boardColumnMenuRef = useRef(null);
|
||||||
|
const { enqueueSnackBar } = useSnackBar();
|
||||||
|
const createCompanyProgress = useCreateCompanyProgress();
|
||||||
|
|
||||||
|
function 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeMenu() {
|
||||||
|
goBackToPreviousHotkeyScope();
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
|
goBackToPreviousHotkeyScope,
|
||||||
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
|
function setMenu(menu: string) {
|
||||||
|
if (menu === 'add') {
|
||||||
|
setHotkeyScopeAndMemorizePreviousScope(
|
||||||
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setOpenMenu(menu);
|
||||||
|
}
|
||||||
|
const [searchFilter] = useRecoilScopedState(
|
||||||
|
relationPickerSearchFilterScopedState,
|
||||||
|
);
|
||||||
|
const companies = useFilteredSearchCompanyQuery({ searchFilter });
|
||||||
|
|
||||||
useListenClickOutside({
|
useListenClickOutside({
|
||||||
refs: [boardColumnMenuRef],
|
refs: [boardColumnMenuRef],
|
||||||
callback: onClose,
|
callback: closeMenu,
|
||||||
});
|
});
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Escape, Key.Enter],
|
[Key.Escape, Key.Enter],
|
||||||
onClose,
|
closeMenu,
|
||||||
BoardColumnHotkeyScope.BoardColumn,
|
BoardColumnHotkeyScope.BoardColumn,
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@ -53,20 +110,37 @@ export function BoardColumnMenu({
|
|||||||
<StyledDropdownMenu>
|
<StyledDropdownMenu>
|
||||||
{openMenu === 'actions' && (
|
{openMenu === 'actions' && (
|
||||||
<StyledDropdownMenuItemsContainer>
|
<StyledDropdownMenuItemsContainer>
|
||||||
<DropdownMenuSelectableItem onClick={() => setOpenMenu('title')}>
|
<DropdownMenuSelectableItem onClick={() => setMenu('title')}>
|
||||||
<IconPencil size={icon.size.md} stroke={icon.stroke.sm} />
|
<IconPencil size={icon.size.md} stroke={icon.stroke.sm} />
|
||||||
Rename
|
Rename
|
||||||
</DropdownMenuSelectableItem>
|
</DropdownMenuSelectableItem>
|
||||||
|
<DropdownMenuSelectableItem onClick={() => setMenu('add')}>
|
||||||
|
<IconPlus size={icon.size.md} stroke={icon.stroke.sm} />
|
||||||
|
New opportunity
|
||||||
|
</DropdownMenuSelectableItem>
|
||||||
</StyledDropdownMenuItemsContainer>
|
</StyledDropdownMenuItemsContainer>
|
||||||
)}
|
)}
|
||||||
{openMenu === 'title' && (
|
{openMenu === 'title' && (
|
||||||
<BoardColumnEditTitleMenu
|
<BoardColumnEditTitleMenu
|
||||||
color={color}
|
color={color}
|
||||||
onClose={onClose}
|
onClose={closeMenu}
|
||||||
onTitleEdit={onTitleEdit}
|
onTitleEdit={onTitleEdit}
|
||||||
title={title}
|
title={title}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{openMenu === 'add' && (
|
||||||
|
<SingleEntitySelect
|
||||||
|
onEntitySelected={(value) => handleCompanySelected(value)}
|
||||||
|
onCancel={closeMenu}
|
||||||
|
entities={{
|
||||||
|
entitiesToSelect: companies.entitiesToSelect,
|
||||||
|
selectedEntity: companies.selectedEntities[0],
|
||||||
|
loading: companies.loading,
|
||||||
|
}}
|
||||||
|
disableBackgroundBlur={true}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</StyledDropdownMenu>
|
</StyledDropdownMenu>
|
||||||
</StyledMenuContainer>
|
</StyledMenuContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -80,6 +80,7 @@ export function EntityBoardColumn({
|
|||||||
totalAmount={boardColumnTotal}
|
totalAmount={boardColumnTotal}
|
||||||
isFirstColumn={column.index === 0}
|
isFirstColumn={column.index === 0}
|
||||||
numChildren={cardIds.length}
|
numChildren={cardIds.length}
|
||||||
|
stageId={column.id}
|
||||||
>
|
>
|
||||||
<BoardColumnCardsContainer droppableProvided={droppableProvided}>
|
<BoardColumnCardsContainer droppableProvided={droppableProvided}>
|
||||||
{cardIds.map((cardId, index) => (
|
{cardIds.map((cardId, index) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user