GH-3183 Add sub actions to quick actions in ActionBar (#3339)

* convert quick action into a dropdown

* GH-3183 import icons

* GH-3183 display dummy sub-actions in dropdown

* Migrate to new Dropdown API

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Deepak Kumar
2024-01-11 18:19:36 +05:30
committed by GitHub
parent e142e4ec79
commit c8aec95325
5 changed files with 69 additions and 10 deletions

View File

@ -14,11 +14,13 @@ import { RecordTableScopeInternalContext } from '@/object-record/record-table/sc
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { import {
IconCheckbox, IconCheckbox,
IconClick,
IconHeart, IconHeart,
IconHeartOff, IconHeartOff,
IconMail,
IconNotes, IconNotes,
IconPuzzle,
IconTrash, IconTrash,
IconWand,
} from '@/ui/display/icon'; } from '@/ui/display/icon';
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState'; import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState'; import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState';
@ -218,9 +220,19 @@ export const useRecordTableContextMenuEntries = (
...(dataExecuteQuickActionOnmentEnabled ...(dataExecuteQuickActionOnmentEnabled
? [ ? [
{ {
label: 'Quick Action', label: 'Actions',
Icon: IconWand, Icon: IconClick,
onClick: () => handleExecuteQuickActionOnClick(), subActions: [
{
label: 'Enrich',
Icon: IconPuzzle,
onClick: () => handleExecuteQuickActionOnClick(),
},
{
label: 'Send to mailjet',
Icon: IconMail,
},
],
}, },
] ]
: []), : []),

View File

@ -33,6 +33,7 @@ export {
IconChevronsRight, IconChevronsRight,
IconChevronUp, IconChevronUp,
IconCircleDot, IconCircleDot,
IconClick,
IconCoins, IconCoins,
IconColorSwatch, IconColorSwatch,
IconMessageCircle as IconComment, IconMessageCircle as IconComment,
@ -90,6 +91,7 @@ export {
IconPlus, IconPlus,
IconPresentation, IconPresentation,
IconProgressCheck, IconProgressCheck,
IconPuzzle,
IconRefresh, IconRefresh,
IconRelationManyToMany, IconRelationManyToMany,
IconRelationOneToMany, IconRelationOneToMany,

View File

@ -55,6 +55,7 @@ export const ActionBar = ({ selectedIds }: ActionBarProps) => {
label={item.label} label={item.label}
onClick={item.onClick} onClick={item.onClick}
key={item.label} key={item.label}
subActions={item?.subActions}
/> />
))} ))}
</StyledContainerActionBar> </StyledContainerActionBar>

View File

@ -1,7 +1,12 @@
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { MenuItem } from 'tsup.ui.index';
import { IconChevronDown } from '@/ui/display/icon';
import { IconComponent } from '@/ui/display/icon/types/IconComponent'; import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { ActionBarItemAccent } from '../types/ActionBarItemAccent'; import { ActionBarItemAccent } from '../types/ActionBarItemAccent';
@ -9,7 +14,8 @@ type ActionBarItemProps = {
Icon: IconComponent; Icon: IconComponent;
label: string; label: string;
accent?: ActionBarItemAccent; accent?: ActionBarItemAccent;
onClick: () => void; onClick?: () => void;
subActions?: ActionBarItemProps[];
}; };
const StyledButton = styled.div<{ accent: ActionBarItemAccent }>` const StyledButton = styled.div<{ accent: ActionBarItemAccent }>`
@ -44,12 +50,49 @@ export const ActionBarItem = ({
Icon, Icon,
accent = 'standard', accent = 'standard',
onClick, onClick,
subActions,
}: ActionBarItemProps) => { }: ActionBarItemProps) => {
const theme = useTheme(); const theme = useTheme();
const dropdownId = `action-bar-item-${label}`;
const { toggleDropdown, closeDropdown } = useDropdown(dropdownId);
return ( return (
<StyledButton accent={accent} onClick={onClick}> <>
{Icon && <Icon size={theme.icon.size.md} />} {Array.isArray(subActions) ? (
<StyledButtonLabel>{label}</StyledButtonLabel> <Dropdown
</StyledButton> dropdownId={dropdownId}
dropdownPlacement="top-start"
dropdownHotkeyScope={{
scope: dropdownId,
}}
clickableComponent={
<StyledButton accent={accent} onClick={toggleDropdown}>
{Icon && <Icon size={theme.icon.size.md} />}
<StyledButtonLabel>{label}</StyledButtonLabel>
<IconChevronDown size={theme.icon.size.md} />
</StyledButton>
}
dropdownComponents={
<DropdownMenuItemsContainer>
{subActions.map((subAction) => (
<MenuItem
key={subAction.label}
text={subAction.label}
LeftIcon={subAction.Icon}
onClick={() => {
closeDropdown();
subAction.onClick?.();
}}
/>
))}
</DropdownMenuItemsContainer>
}
/>
) : (
<StyledButton accent={accent} onClick={onClick}>
{Icon && <Icon size={theme.icon.size.md} />}
<StyledButtonLabel>{label}</StyledButtonLabel>
</StyledButton>
)}
</>
); );
}; };

View File

@ -6,5 +6,6 @@ export type ActionBarEntry = {
label: string; label: string;
Icon: IconComponent; Icon: IconComponent;
accent?: ActionBarItemAccent; accent?: ActionBarItemAccent;
onClick: () => void; onClick?: () => void;
subActions?: ActionBarEntry[];
}; };