Refactor/new menu item (#1448)

* wip

* finished

* Added disabled

* Fixed disabled

* Finished cleaning

* Minor fixes from merge

* Added docs

* Added PascalCase

* Fix from review

* Fixes from merge

* Fix lint

* Fixed storybook tests
This commit is contained in:
Lucas Bordeau
2023-09-06 16:41:26 +02:00
committed by GitHub
parent 5c7660f588
commit 28ca9a9e49
96 changed files with 816 additions and 918 deletions

View File

@ -2,6 +2,7 @@ import React from 'react';
import styled from '@emotion/styled';
import { Tag } from '@/ui/tag/components/Tag';
import { ThemeColor } from '@/ui/theme/constants/colors';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { BoardColumnHotkeyScope } from '../types/BoardColumnHotkeyScope';
@ -52,7 +53,7 @@ const StyledNumChildren = styled.div`
`;
export type BoardColumnProps = {
color: string;
color?: ThemeColor;
title: string;
onDelete?: (id: string) => void;
onTitleEdit: (title: string, color: string) => void;
@ -97,7 +98,7 @@ export function BoardColumn({
return (
<StyledColumn isFirstColumn={isFirstColumn}>
<StyledHeader>
<Tag onClick={handleTitleClick} color={color} text={title} />
<Tag onClick={handleTitleClick} color={color ?? 'gray'} text={title} />
{!!totalAmount && <StyledAmount>${totalAmount}</StyledAmount>}
<StyledNumChildren>{numChildren}</StyledNumChildren>
</StyledHeader>
@ -107,7 +108,7 @@ export function BoardColumn({
onDelete={onDelete}
onTitleEdit={onTitleEdit}
title={title}
color={color}
color={color ?? 'gray'}
stageId={stageId}
/>
)}

View File

@ -1,9 +1,10 @@
import { ChangeEvent, useState } from 'react';
import styled from '@emotion/styled';
import { DropdownMenuSelectableItem } from '@/ui/dropdown/components/DropdownMenuSelectableItem';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
import { MenuItemSelectColor } from '@/ui/menu-item/components/MenuItemSelectColor';
import { ThemeColor } from '@/ui/theme/constants/colors';
import { textInputStyle } from '@/ui/theme/constants/effects';
import { debounce } from '~/utils/debounce';
@ -32,21 +33,15 @@ export type BoardColumnEditTitleMenuProps = {
onClose: () => void;
title: string;
onTitleEdit: (title: string, color: string) => void;
color: string;
color: ThemeColor;
};
const StyledColorSample = styled.div<{ colorName: string }>`
background-color: ${({ theme, colorName }) =>
theme.tag.background[colorName]};
border: 1px solid
${({ theme, colorName }) =>
theme.color[colorName as keyof typeof theme.color]};
border-radius: ${({ theme }) => theme.border.radius.sm};
height: 12px;
width: 12px;
`;
type ColumnColorOption = {
name: string;
id: ThemeColor;
};
export const COLOR_OPTIONS = [
export const COLUMN_COLOR_OPTIONS: ColumnColorOption[] = [
{ name: 'Green', id: 'green' },
{ name: 'Turquoise', id: 'turquoise' },
{ name: 'Sky', id: 'sky' },
@ -85,18 +80,17 @@ export function BoardColumnEditTitleMenu({
/>
</StyledEditTitleContainer>
<StyledDropdownMenuSeparator />
{COLOR_OPTIONS.map((colorOption) => (
<DropdownMenuSelectableItem
{COLUMN_COLOR_OPTIONS.map((colorOption) => (
<MenuItemSelectColor
key={colorOption.name}
onClick={() => {
onTitleEdit(title, colorOption.id);
onClose();
}}
color={colorOption.id}
selected={colorOption.id === color}
>
<StyledColorSample colorName={colorOption.id} />
{colorOption.name}
</DropdownMenuSelectableItem>
text={colorOption.name}
/>
))}
</StyledDropdownMenuItemsContainer>
);

View File

@ -5,7 +5,6 @@ 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 { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { IconPencil, IconPlus, IconTrash } from '@/ui/icon';
@ -13,8 +12,9 @@ import { SingleEntitySelect } from '@/ui/input/relation-picker/components/Single
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 { icon } from '@/ui/theme/constants/icon';
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';
@ -32,7 +32,7 @@ const StyledMenuContainer = styled.div`
`;
type OwnProps = {
color: string;
color: ThemeColor;
onClose: () => void;
onDelete?: (id: string) => void;
onTitleEdit: (title: string, color: string) => void;
@ -52,7 +52,7 @@ export function BoardColumnMenu({
}: OwnProps) {
const [currentMenu, setCurrentMenu] = useState('actions');
const [boardColumns, setBoardColumns] = useRecoilState(boardColumnsState);
const [, setBoardColumns] = useRecoilState(boardColumnsState);
const boardColumnMenuRef = useRef(null);
@ -130,21 +130,21 @@ export function BoardColumnMenu({
<StyledDropdownMenu>
{currentMenu === 'actions' && (
<StyledDropdownMenuItemsContainer>
<DropdownMenuSelectableItem onClick={() => setMenu('title')}>
<IconPencil size={icon.size.md} stroke={icon.stroke.sm} />
Rename
</DropdownMenuSelectableItem>
<DropdownMenuSelectableItem
disabled={boardColumns.length <= 1}
<MenuItem
onClick={() => setMenu('title')}
LeftIcon={IconPencil}
text="Rename"
/>
<MenuItem
onClick={handleDelete}
>
<IconTrash size={icon.size.md} stroke={icon.stroke.sm} />
Delete
</DropdownMenuSelectableItem>
<DropdownMenuSelectableItem onClick={() => setMenu('add')}>
<IconPlus size={icon.size.md} stroke={icon.stroke.sm} />
New opportunity
</DropdownMenuSelectableItem>
LeftIcon={IconTrash}
text="Delete"
/>
<MenuItem
onClick={() => setMenu('add')}
LeftIcon={IconPlus}
text="New opportunity"
/>
</StyledDropdownMenuItemsContainer>
)}
{currentMenu === 'title' && (

View File

@ -7,18 +7,19 @@ import { v4 } from 'uuid';
import { DropdownMenuHeader } from '@/ui/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuItem } from '@/ui/dropdown/components/DropdownMenuItem';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import {
IconChevronLeft,
IconChevronRight,
IconLayoutKanban,
IconPlus,
IconSettings,
} from '@/ui/icon';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { MenuItemNavigate } from '@/ui/menu-item/components/MenuItemNavigate';
import { ThemeColor } from '@/ui/theme/constants/colors';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
@ -35,16 +36,18 @@ const StyledIconSettings = styled(IconSettings)`
margin-right: ${({ theme }) => theme.spacing(1)};
`;
const StyledIconChevronRight = styled(IconChevronRight)`
color: ${({ theme }) => theme.font.color.tertiary};
margin-left: auto;
`;
enum BoardOptionsMenu {
StageCreation = 'StageCreation',
Stages = 'Stages',
}
type ColumnForCreate = {
id: string;
colorCode: ThemeColor;
index: number;
title: string;
};
export function BoardOptionsDropdownContent({
customHotkeyScope,
onStageAdd,
@ -68,7 +71,7 @@ export function BoardOptionsDropdownContent({
)
return;
const columnToCreate = {
const columnToCreate: ColumnForCreate = {
id: v4(),
colorCode: 'gray',
index: boardColumns.length,
@ -113,32 +116,26 @@ export function BoardOptionsDropdownContent({
</DropdownMenuHeader>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuItemsContainer>
<DropdownMenuItem
<MenuItemNavigate
onClick={() => setCurrentMenu(BoardOptionsMenu.Stages)}
>
<IconLayoutKanban size={theme.icon.size.md} />
Stages
<StyledIconChevronRight size={theme.icon.size.sm} />
</DropdownMenuItem>
LeftIcon={IconLayoutKanban}
text="Stages"
/>
</StyledDropdownMenuItemsContainer>
</>
)}
{currentMenu === BoardOptionsMenu.Stages && (
<>
<DropdownMenuHeader
startIcon={<IconChevronLeft size={theme.icon.size.md} />}
onClick={resetMenu}
>
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={resetMenu}>
Stages
</DropdownMenuHeader>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuItemsContainer>
<DropdownMenuItem
<MenuItem
onClick={() => setCurrentMenu(BoardOptionsMenu.StageCreation)}
>
<IconPlus size={theme.icon.size.md} />
Add stage
</DropdownMenuItem>
LeftIcon={IconPlus}
text="Add stage"
/>
</StyledDropdownMenuItemsContainer>
</>
)}

View File

@ -4,7 +4,7 @@ import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import {
BoardColumnEditTitleMenu,
COLOR_OPTIONS,
COLUMN_COLOR_OPTIONS,
} from '../BoardColumnEditTitleMenu';
const meta: Meta<typeof BoardColumnEditTitleMenu> = {
@ -14,7 +14,7 @@ const meta: Meta<typeof BoardColumnEditTitleMenu> = {
argTypes: {
color: {
control: 'select',
options: COLOR_OPTIONS.map(({ id }) => id),
options: COLUMN_COLOR_OPTIONS.map(({ id }) => id),
},
},
args: { color: 'green', title: 'Column title' },

View File

@ -16,7 +16,7 @@ export function useBoardContextMenuEntries() {
setContextMenuEntries([
<ContextMenuEntry
label="Delete"
icon={<IconTrash size={16} />}
Icon={IconTrash}
accent="danger"
onClick={() => deleteSelectedBoardCards()}
key="delete"

View File

@ -1,6 +1,8 @@
import { ThemeColor } from '@/ui/theme/constants/colors';
export type BoardColumnDefinition = {
id: string;
title: string;
index: number;
colorCode: string;
colorCode?: ThemeColor;
};