From 85a6d0aa129776950831e8a38a9adfbc6b0deb38 Mon Sep 17 00:00:00 2001 From: brendanlaschke Date: Fri, 15 Sep 2023 18:51:02 +0300 Subject: [PATCH] Refactor action bar entries and context menu entries (#1608) - refactored actionbar entries / context menu entries --- .../hooks/useCompanyTableActionBarEntries.tsx | 36 +++++++++---------- .../useCompanyTableContextMenuEntries.tsx | 36 +++++++++---------- .../usePeopleTableContextMenuEntries.tsx | 36 +++++++++---------- .../hooks/usePersonTableActionBarEntries.tsx | 36 +++++++++---------- .../ui/action-bar/components/ActionBar.tsx | 12 ++++++- .../{ActionBarEntry.tsx => ActionBarItem.tsx} | 24 ++++++------- .../states/actionBarEntriesState.ts | 5 +-- .../ui/action-bar/types/ActionBarEntry.ts | 10 ++++++ .../action-bar/types/ActionBarItemAccent.ts | 1 + .../board/hooks/useBoardActionBarEntries.tsx | 14 ++++---- .../hooks/useBoardContextMenuEntries.tsx | 14 ++++---- .../context-menu/components/ContextMenu.tsx | 12 ++++++- ...ntextMenuEntry.tsx => ContextMenuItem.tsx} | 6 ++-- .../states/contextMenuEntriesState.ts | 5 +-- .../ui/context-menu/types/ContextMenuEntry.ts | 10 ++++++ .../types/ContextMenuItemAccent.ts | 1 + 16 files changed, 141 insertions(+), 117 deletions(-) rename front/src/modules/ui/action-bar/components/{ActionBarEntry.tsx => ActionBarItem.tsx} (67%) create mode 100644 front/src/modules/ui/action-bar/types/ActionBarEntry.ts create mode 100644 front/src/modules/ui/action-bar/types/ActionBarItemAccent.ts rename front/src/modules/ui/context-menu/components/{ContextMenuEntry.tsx => ContextMenuItem.tsx} (72%) create mode 100644 front/src/modules/ui/context-menu/types/ContextMenuEntry.ts create mode 100644 front/src/modules/ui/context-menu/types/ContextMenuItemAccent.ts diff --git a/front/src/modules/companies/hooks/useCompanyTableActionBarEntries.tsx b/front/src/modules/companies/hooks/useCompanyTableActionBarEntries.tsx index cbef0d7b8..90b25440c 100644 --- a/front/src/modules/companies/hooks/useCompanyTableActionBarEntries.tsx +++ b/front/src/modules/companies/hooks/useCompanyTableActionBarEntries.tsx @@ -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([ - handleActivityClick(ActivityType.Note)} - key="note" - />, - handleActivityClick(ActivityType.Task)} - key="task" - />, - 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(), + }, ]), }; } diff --git a/front/src/modules/companies/hooks/useCompanyTableContextMenuEntries.tsx b/front/src/modules/companies/hooks/useCompanyTableContextMenuEntries.tsx index 7dbf90f28..b25d66cab 100644 --- a/front/src/modules/companies/hooks/useCompanyTableContextMenuEntries.tsx +++ b/front/src/modules/companies/hooks/useCompanyTableContextMenuEntries.tsx @@ -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([ - handleButtonClick(ActivityType.Note)} - key="note" - />, - handleButtonClick(ActivityType.Task)} - key="task" - />, - 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(), + }, ]), }; } diff --git a/front/src/modules/people/hooks/usePeopleTableContextMenuEntries.tsx b/front/src/modules/people/hooks/usePeopleTableContextMenuEntries.tsx index b7341f86e..348cbd94e 100644 --- a/front/src/modules/people/hooks/usePeopleTableContextMenuEntries.tsx +++ b/front/src/modules/people/hooks/usePeopleTableContextMenuEntries.tsx @@ -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([ - handleActivityClick(ActivityType.Note)} - key="note" - />, - handleActivityClick(ActivityType.Task)} - key="task" - />, - , + { + label: 'Note', + Icon: IconNotes, + onClick: () => handleActivityClick(ActivityType.Note), + }, + { + label: 'Task', + Icon: IconCheckbox, + onClick: () => handleActivityClick(ActivityType.Task), + }, + { + label: 'Delete', + Icon: IconTrash, + accent: 'danger', + onClick: () => handleDeleteClick(), + }, ]), }; } diff --git a/front/src/modules/people/hooks/usePersonTableActionBarEntries.tsx b/front/src/modules/people/hooks/usePersonTableActionBarEntries.tsx index 3c71d576d..1fc08ed8d 100644 --- a/front/src/modules/people/hooks/usePersonTableActionBarEntries.tsx +++ b/front/src/modules/people/hooks/usePersonTableActionBarEntries.tsx @@ -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([ - handleActivityClick(ActivityType.Note)} - key="note" - />, - handleActivityClick(ActivityType.Task)} - key="task" - />, - , + { + label: 'Note', + Icon: IconNotes, + onClick: () => handleActivityClick(ActivityType.Note), + }, + { + label: 'Task', + Icon: IconCheckbox, + onClick: () => handleActivityClick(ActivityType.Task), + }, + { + label: 'Delete', + Icon: IconTrash, + accent: 'danger', + onClick: () => handleDeleteClick(), + }, ]), }; } diff --git a/front/src/modules/ui/action-bar/components/ActionBar.tsx b/front/src/modules/ui/action-bar/components/ActionBar.tsx index bfbb4d0f9..3257bc954 100644 --- a/front/src/modules/ui/action-bar/components/ActionBar.tsx +++ b/front/src/modules/ui/action-bar/components/ActionBar.tsx @@ -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 ( - {actionBarEntries} + {actionBarEntries.map((item) => ( + + ))} ); } diff --git a/front/src/modules/ui/action-bar/components/ActionBarEntry.tsx b/front/src/modules/ui/action-bar/components/ActionBarItem.tsx similarity index 67% rename from front/src/modules/ui/action-bar/components/ActionBarEntry.tsx rename to front/src/modules/ui/action-bar/components/ActionBarItem.tsx index 6236b52cd..568f30cda 100644 --- a/front/src/modules/ui/action-bar/components/ActionBarEntry.tsx +++ b/front/src/modules/ui/action-bar/components/ActionBarItem.tsx @@ -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` +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` 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 ( - + {Icon && } {label} diff --git a/front/src/modules/ui/action-bar/states/actionBarEntriesState.ts b/front/src/modules/ui/action-bar/states/actionBarEntriesState.ts index 81b436523..2e9d0cf61 100644 --- a/front/src/modules/ui/action-bar/states/actionBarEntriesState.ts +++ b/front/src/modules/ui/action-bar/states/actionBarEntriesState.ts @@ -1,7 +1,8 @@ -import { ReactElement } from 'react'; import { atom } from 'recoil'; -export const actionBarEntriesState = atom({ +import { ActionBarEntry } from '../types/ActionBarEntry'; + +export const actionBarEntriesState = atom({ key: 'actionBarEntriesState', default: [], }); diff --git a/front/src/modules/ui/action-bar/types/ActionBarEntry.ts b/front/src/modules/ui/action-bar/types/ActionBarEntry.ts new file mode 100644 index 000000000..e683361d4 --- /dev/null +++ b/front/src/modules/ui/action-bar/types/ActionBarEntry.ts @@ -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; +}; diff --git a/front/src/modules/ui/action-bar/types/ActionBarItemAccent.ts b/front/src/modules/ui/action-bar/types/ActionBarItemAccent.ts new file mode 100644 index 000000000..6000a924f --- /dev/null +++ b/front/src/modules/ui/action-bar/types/ActionBarItemAccent.ts @@ -0,0 +1 @@ +export type ActionBarItemAccent = 'standard' | 'danger'; diff --git a/front/src/modules/ui/board/hooks/useBoardActionBarEntries.tsx b/front/src/modules/ui/board/hooks/useBoardActionBarEntries.tsx index 671e0c28a..1103a919b 100644 --- a/front/src/modules/ui/board/hooks/useBoardActionBarEntries.tsx +++ b/front/src/modules/ui/board/hooks/useBoardActionBarEntries.tsx @@ -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([ - , + { + label: 'Delete', + Icon: IconTrash, + accent: 'danger', + onClick: deleteSelectedBoardCards, + }, ]), }; } diff --git a/front/src/modules/ui/board/hooks/useBoardContextMenuEntries.tsx b/front/src/modules/ui/board/hooks/useBoardContextMenuEntries.tsx index 29fee01e0..0bdb9d7e1 100644 --- a/front/src/modules/ui/board/hooks/useBoardContextMenuEntries.tsx +++ b/front/src/modules/ui/board/hooks/useBoardContextMenuEntries.tsx @@ -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([ - deleteSelectedBoardCards()} - key="delete" - />, + { + label: 'Delete', + Icon: IconTrash, + accent: 'danger', + onClick: () => deleteSelectedBoardCards(), + }, ]), }; } diff --git a/front/src/modules/ui/context-menu/components/ContextMenu.tsx b/front/src/modules/ui/context-menu/components/ContextMenu.tsx index dc1568999..40ef7a05f 100644 --- a/front/src/modules/ui/context-menu/components/ContextMenu.tsx +++ b/front/src/modules/ui/context-menu/components/ContextMenu.tsx @@ -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) { > - {contextMenuEntries} + {contextMenuEntries.map((item) => ( + + ))} diff --git a/front/src/modules/ui/context-menu/components/ContextMenuEntry.tsx b/front/src/modules/ui/context-menu/components/ContextMenuItem.tsx similarity index 72% rename from front/src/modules/ui/context-menu/components/ContextMenuEntry.tsx rename to front/src/modules/ui/context-menu/components/ContextMenuItem.tsx index 1c07c11b1..40625a5cb 100644 --- a/front/src/modules/ui/context-menu/components/ContextMenuEntry.tsx +++ b/front/src/modules/ui/context-menu/components/ContextMenuItem.tsx @@ -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', diff --git a/front/src/modules/ui/context-menu/states/contextMenuEntriesState.ts b/front/src/modules/ui/context-menu/states/contextMenuEntriesState.ts index e79628b6a..e5ba5396d 100644 --- a/front/src/modules/ui/context-menu/states/contextMenuEntriesState.ts +++ b/front/src/modules/ui/context-menu/states/contextMenuEntriesState.ts @@ -1,7 +1,8 @@ -import { ReactElement } from 'react'; import { atom } from 'recoil'; -export const contextMenuEntriesState = atom({ +import { ContextMenuEntry } from '../types/ContextMenuEntry'; + +export const contextMenuEntriesState = atom({ key: 'contextMenuEntriesState', default: [], }); diff --git a/front/src/modules/ui/context-menu/types/ContextMenuEntry.ts b/front/src/modules/ui/context-menu/types/ContextMenuEntry.ts new file mode 100644 index 000000000..8c39d2700 --- /dev/null +++ b/front/src/modules/ui/context-menu/types/ContextMenuEntry.ts @@ -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; +}; diff --git a/front/src/modules/ui/context-menu/types/ContextMenuItemAccent.ts b/front/src/modules/ui/context-menu/types/ContextMenuItemAccent.ts new file mode 100644 index 000000000..ceae88f5b --- /dev/null +++ b/front/src/modules/ui/context-menu/types/ContextMenuItemAccent.ts @@ -0,0 +1 @@ +export type ContextMenuItemAccent = 'default' | 'danger';