Refactor action bar entries and context menu entries (#1608)

- refactored actionbar entries / context menu entries
This commit is contained in:
brendanlaschke
2023-09-15 18:51:02 +03:00
committed by GitHub
parent 955deaf878
commit 85a6d0aa12
16 changed files with 141 additions and 117 deletions

View File

@ -2,7 +2,6 @@ import { useSetRecoilState } from 'recoil';
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
import { ActionBarEntry } from '@/ui/action-bar/components/ActionBarEntry';
import { actionBarEntriesState } from '@/ui/action-bar/states/actionBarEntriesState';
import { IconCheckbox, IconNotes, IconTrash } from '@/ui/icon';
import { ActivityType } from '~/generated/graphql';
@ -23,25 +22,22 @@ export function useCompanyTableActionBarEntries() {
return {
setActionBarEntries: () =>
setActionBarEntries([
<ActionBarEntry
label="Note"
Icon={IconNotes}
onClick={() => handleActivityClick(ActivityType.Note)}
key="note"
/>,
<ActionBarEntry
label="Task"
Icon={IconCheckbox}
onClick={() => handleActivityClick(ActivityType.Task)}
key="task"
/>,
<ActionBarEntry
label="Delete"
Icon={IconTrash}
type="danger"
onClick={() => deleteSelectedCompanies()}
key="delete"
/>,
{
label: 'Note',
Icon: IconNotes,
onClick: () => handleActivityClick(ActivityType.Note),
},
{
label: 'Task',
Icon: IconCheckbox,
onClick: () => handleActivityClick(ActivityType.Task),
},
{
label: 'Delete',
Icon: IconTrash,
accent: 'danger',
onClick: () => deleteSelectedCompanies(),
},
]),
};
}

View File

@ -2,7 +2,6 @@ import { useSetRecoilState } from 'recoil';
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
import { ContextMenuEntry } from '@/ui/context-menu/components/ContextMenuEntry';
import { contextMenuEntriesState } from '@/ui/context-menu/states/contextMenuEntriesState';
import { IconCheckbox, IconNotes, IconTrash } from '@/ui/icon';
import { ActivityType } from '~/generated/graphql';
@ -24,25 +23,22 @@ export function useCompanyTableContextMenuEntries() {
return {
setContextMenuEntries: () =>
setContextMenuEntries([
<ContextMenuEntry
label="Note"
Icon={IconNotes}
onClick={() => handleButtonClick(ActivityType.Note)}
key="note"
/>,
<ContextMenuEntry
label="Task"
Icon={IconCheckbox}
onClick={() => handleButtonClick(ActivityType.Task)}
key="task"
/>,
<ContextMenuEntry
label="Delete"
Icon={IconTrash}
accent="danger"
onClick={() => deleteSelectedCompanies()}
key="delete"
/>,
{
label: 'Note',
Icon: IconNotes,
onClick: () => handleButtonClick(ActivityType.Note),
},
{
label: 'Task',
Icon: IconCheckbox,
onClick: () => handleButtonClick(ActivityType.Task),
},
{
label: 'Delete',
Icon: IconTrash,
accent: 'danger',
onClick: () => deleteSelectedCompanies(),
},
]),
};
}

View File

@ -3,7 +3,6 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
import { ContextMenuEntry } from '@/ui/context-menu/components/ContextMenuEntry';
import { contextMenuEntriesState } from '@/ui/context-menu/states/contextMenuEntriesState';
import { IconCheckbox, IconNotes, IconTrash } from '@/ui/icon';
import { useResetTableRowSelection } from '@/ui/table/hooks/useResetTableRowSelection';
@ -58,25 +57,22 @@ export function usePersonTableContextMenuEntries() {
return {
setContextMenuEntries: () =>
setContextMenuEntries([
<ContextMenuEntry
label="Note"
Icon={IconNotes}
onClick={() => handleActivityClick(ActivityType.Note)}
key="note"
/>,
<ContextMenuEntry
label="Task"
Icon={IconCheckbox}
onClick={() => handleActivityClick(ActivityType.Task)}
key="task"
/>,
<ContextMenuEntry
label="Delete"
Icon={IconTrash}
accent="danger"
onClick={handleDeleteClick}
key="delete"
/>,
{
label: 'Note',
Icon: IconNotes,
onClick: () => handleActivityClick(ActivityType.Note),
},
{
label: 'Task',
Icon: IconCheckbox,
onClick: () => handleActivityClick(ActivityType.Task),
},
{
label: 'Delete',
Icon: IconTrash,
accent: 'danger',
onClick: () => handleDeleteClick(),
},
]),
};
}

View File

@ -3,7 +3,6 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
import { ActionBarEntry } from '@/ui/action-bar/components/ActionBarEntry';
import { actionBarEntriesState } from '@/ui/action-bar/states/actionBarEntriesState';
import { IconCheckbox, IconNotes, IconTrash } from '@/ui/icon';
import { useResetTableRowSelection } from '@/ui/table/hooks/useResetTableRowSelection';
@ -62,25 +61,22 @@ export function usePersonTableActionBarEntries() {
return {
setActionBarEntries: () =>
setActionBarEntries([
<ActionBarEntry
label="Note"
Icon={IconNotes}
onClick={() => handleActivityClick(ActivityType.Note)}
key="note"
/>,
<ActionBarEntry
label="Task"
Icon={IconCheckbox}
onClick={() => handleActivityClick(ActivityType.Task)}
key="task"
/>,
<ActionBarEntry
label="Delete"
Icon={IconTrash}
type="danger"
onClick={handleDeleteClick}
key="delete"
/>,
{
label: 'Note',
Icon: IconNotes,
onClick: () => handleActivityClick(ActivityType.Note),
},
{
label: 'Task',
Icon: IconCheckbox,
onClick: () => handleActivityClick(ActivityType.Task),
},
{
label: 'Delete',
Icon: IconTrash,
accent: 'danger',
onClick: () => handleDeleteClick(),
},
]),
};
}

View File

@ -7,6 +7,8 @@ import { contextMenuIsOpenState } from '@/ui/context-menu/states/contextMenuIsOp
import { actionBarOpenState } from '../states/actionBarIsOpenState';
import { ActionBarItem } from './ActionBarItem';
type OwnProps = {
selectedIds: string[];
};
@ -42,7 +44,15 @@ export function ActionBar({ selectedIds }: OwnProps) {
}
return (
<StyledContainerActionBar className="action-bar" ref={wrapperRef}>
{actionBarEntries}
{actionBarEntries.map((item) => (
<ActionBarItem
Icon={item.Icon}
accent={item.accent}
label={item.label}
onClick={item.onClick}
key={item.label}
/>
))}
</StyledContainerActionBar>
);
}

View File

@ -3,21 +3,19 @@ import styled from '@emotion/styled';
import { IconComponent } from '@/ui/icon/types/IconComponent';
import { ActionBarItemAccent } from '../types/ActionBarItemAccent';
type OwnProps = {
Icon: IconComponent;
label: string;
type?: 'standard' | 'danger';
accent?: ActionBarItemAccent;
onClick: () => void;
};
type StyledButtonProps = {
type: 'standard' | 'danger';
};
const StyledButton = styled.div<StyledButtonProps>`
const StyledButton = styled.div<{ accent: ActionBarItemAccent }>`
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${(props) =>
props.type === 'danger'
props.accent === 'danger'
? props.theme.color.red
: props.theme.font.color.secondary};
cursor: pointer;
@ -29,8 +27,10 @@ const StyledButton = styled.div<StyledButtonProps>`
user-select: none;
&:hover {
background: ${({ theme, type }) =>
type === 'danger' ? theme.tag.background.red : theme.background.tertiary};
background: ${({ theme, accent }) =>
accent === 'danger'
? theme.tag.background.red
: theme.background.tertiary};
}
`;
@ -39,15 +39,15 @@ const StyledButtonLabel = styled.div`
margin-left: ${({ theme }) => theme.spacing(2)};
`;
export function ActionBarEntry({
export function ActionBarItem({
label,
Icon,
type = 'standard',
accent = 'standard',
onClick,
}: OwnProps) {
const theme = useTheme();
return (
<StyledButton type={type} onClick={onClick}>
<StyledButton accent={accent} onClick={onClick}>
{Icon && <Icon size={theme.icon.size.md} />}
<StyledButtonLabel>{label}</StyledButtonLabel>
</StyledButton>

View File

@ -1,7 +1,8 @@
import { ReactElement } from 'react';
import { atom } from 'recoil';
export const actionBarEntriesState = atom<ReactElement[]>({
import { ActionBarEntry } from '../types/ActionBarEntry';
export const actionBarEntriesState = atom<ActionBarEntry[]>({
key: 'actionBarEntriesState',
default: [],
});

View File

@ -0,0 +1,10 @@
import { IconComponent } from '@/ui/icon/types/IconComponent';
import { ActionBarItemAccent } from './ActionBarItemAccent';
export type ActionBarEntry = {
label: string;
Icon: IconComponent;
accent?: ActionBarItemAccent;
onClick: () => void;
};

View File

@ -0,0 +1 @@
export type ActionBarItemAccent = 'standard' | 'danger';

View File

@ -1,6 +1,5 @@
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';
@ -14,13 +13,12 @@ export function useBoardActionBarEntries() {
return {
setActionBarEntries: () =>
setActionBarEntries([
<ActionBarEntry
label="Delete"
Icon={IconTrash}
type="danger"
onClick={deleteSelectedBoardCards}
key="delete"
/>,
{
label: 'Delete',
Icon: IconTrash,
accent: 'danger',
onClick: deleteSelectedBoardCards,
},
]),
};
}

View File

@ -1,6 +1,5 @@
import { useSetRecoilState } from 'recoil';
import { ContextMenuEntry } from '@/ui/context-menu/components/ContextMenuEntry';
import { contextMenuEntriesState } from '@/ui/context-menu/states/contextMenuEntriesState';
import { IconTrash } from '@/ui/icon';
@ -14,13 +13,12 @@ export function useBoardContextMenuEntries() {
return {
setContextMenuEntries: () =>
setContextMenuEntries([
<ContextMenuEntry
label="Delete"
Icon={IconTrash}
accent="danger"
onClick={() => deleteSelectedBoardCards()}
key="delete"
/>,
{
label: 'Delete',
Icon: IconTrash,
accent: 'danger',
onClick: () => deleteSelectedBoardCards(),
},
]),
};
}

View File

@ -12,6 +12,8 @@ import { contextMenuEntriesState } from '../states/contextMenuEntriesState';
import { contextMenuIsOpenState } from '../states/contextMenuIsOpenState';
import { PositionType } from '../types/PositionType';
import { ContextMenuItem } from './ContextMenuItem';
type OwnProps = {
selectedIds: string[];
};
@ -66,7 +68,15 @@ export function ContextMenu({ selectedIds }: OwnProps) {
>
<StyledDropdownMenu>
<StyledDropdownMenuItemsContainer>
{contextMenuEntries}
{contextMenuEntries.map((item) => (
<ContextMenuItem
Icon={item.Icon}
label={item.label}
accent={item.accent}
onClick={item.onClick}
key={item.label}
/>
))}
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
</StyledContainerContextMenu>

View File

@ -1,16 +1,16 @@
import { IconComponent } from '@/ui/icon/types/IconComponent';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
type ContextMenuEntryAccent = 'default' | 'danger';
import { ContextMenuItemAccent } from '../types/ContextMenuItemAccent';
type OwnProps = {
Icon: IconComponent;
label: string;
accent?: ContextMenuEntryAccent;
accent?: ContextMenuItemAccent;
onClick: () => void;
};
export function ContextMenuEntry({
export function ContextMenuItem({
label,
Icon,
accent = 'default',

View File

@ -1,7 +1,8 @@
import { ReactElement } from 'react';
import { atom } from 'recoil';
export const contextMenuEntriesState = atom<ReactElement[]>({
import { ContextMenuEntry } from '../types/ContextMenuEntry';
export const contextMenuEntriesState = atom<ContextMenuEntry[]>({
key: 'contextMenuEntriesState',
default: [],
});

View File

@ -0,0 +1,10 @@
import { IconComponent } from '@/ui/icon/types/IconComponent';
import { ContextMenuItemAccent } from './ContextMenuItemAccent';
export type ContextMenuEntry = {
label: string;
Icon: IconComponent;
accent?: ContextMenuItemAccent;
onClick: () => void;
};

View File

@ -0,0 +1 @@
export type ContextMenuItemAccent = 'default' | 'danger';