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:
@ -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,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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[];
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user