[DASHBOARDS] Widget duplication (#15979)
## Widget duplication - Created a shared component for the option menu shared by the record page, the dashboards and the workflows - Fix arrow selection in the option menu in workflows, which wasn't working - Scroll to the new widget after creation and open the new widget settings https://github.com/user-attachments/assets/47b8dade-44bd-4ba2-a81c-01b09e8718d3
This commit is contained in:
+70
-64
@@ -1,14 +1,13 @@
|
||||
import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandMenu';
|
||||
import { useCommandMenuWorkflowIdOrThrow } from '@/command-menu/pages/workflow/hooks/useCommandMenuWorkflowIdOrThrow';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { OptionsDropdownMenu } from '@/ui/layout/dropdown/components/OptionsDropdownMenu';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useDeleteStep } from '@/workflow/workflow-steps/hooks/useDeleteStep';
|
||||
import { useDuplicateStep } from '@/workflow/workflow-steps/hooks/useDuplicateStep';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useId } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -16,7 +15,6 @@ import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
import { IconCopyPlus, IconPencil, IconTrash } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { getOsControlSymbol } from 'twenty-ui/utilities';
|
||||
|
||||
export const WorkflowStepFooter = ({
|
||||
stepId,
|
||||
@@ -27,7 +25,6 @@ export const WorkflowStepFooter = ({
|
||||
}) => {
|
||||
const dropdownId = useId();
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const { duplicateStep } = useDuplicateStep();
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
const workflowId = useCommandMenuWorkflowIdOrThrow();
|
||||
@@ -39,66 +36,75 @@ export const WorkflowStepFooter = ({
|
||||
const shouldPinDeleteButton =
|
||||
!isDefined(additionalActions) || additionalActions.length === 0;
|
||||
|
||||
const selectableItemIdArray = [
|
||||
'change-node-type',
|
||||
...(stepId !== TRIGGER_STEP_ID ? ['duplicate'] : []),
|
||||
...(!shouldPinDeleteButton ? ['delete'] : []),
|
||||
];
|
||||
|
||||
const handleChangeNodeType = () => {
|
||||
closeDropdown(dropdownId);
|
||||
|
||||
if (stepId === TRIGGER_STEP_ID) {
|
||||
openWorkflowTriggerTypeInCommandMenu(workflowId);
|
||||
} else {
|
||||
openWorkflowEditStepTypeInCommandMenu(workflowId);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDuplicateNode = () => {
|
||||
closeDropdown(dropdownId);
|
||||
duplicateStep({ stepId });
|
||||
};
|
||||
|
||||
const handleDeleteNode = () => {
|
||||
closeDropdown(dropdownId);
|
||||
deleteStep(stepId);
|
||||
};
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
selectedItemIdComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const OptionsDropdown = (
|
||||
<Dropdown
|
||||
<OptionsDropdownMenu
|
||||
dropdownId={dropdownId}
|
||||
data-select-disable
|
||||
clickableComponent={
|
||||
<Button
|
||||
size="small"
|
||||
title={t`Options`}
|
||||
hotkeys={[getOsControlSymbol(), 'O']}
|
||||
selectableListId={dropdownId}
|
||||
selectableItemIdArray={selectableItemIdArray}
|
||||
>
|
||||
<SelectableListItem
|
||||
itemId="change-node-type"
|
||||
onEnter={handleChangeNodeType}
|
||||
>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'change-node-type'}
|
||||
onClick={handleChangeNodeType}
|
||||
text={t`Change node type`}
|
||||
LeftIcon={IconPencil}
|
||||
/>
|
||||
}
|
||||
dropdownPlacement="top-end"
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(2), 10) }}
|
||||
globalHotkeysConfig={{
|
||||
enableGlobalHotkeysWithModifiers: true,
|
||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||
}}
|
||||
dropdownComponents={
|
||||
<DropdownContent>
|
||||
<DropdownMenuItemsContainer>
|
||||
<SelectableList
|
||||
selectableListInstanceId={dropdownId}
|
||||
focusId={dropdownId}
|
||||
selectableItemIdArray={['change-node-type', 'duplicate']}
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
closeDropdown(dropdownId);
|
||||
stepId === TRIGGER_STEP_ID
|
||||
? openWorkflowTriggerTypeInCommandMenu(workflowId)
|
||||
: openWorkflowEditStepTypeInCommandMenu(workflowId);
|
||||
}}
|
||||
text={t`Change node type`}
|
||||
LeftIcon={IconPencil}
|
||||
/>
|
||||
{stepId !== TRIGGER_STEP_ID && (
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
closeDropdown(dropdownId);
|
||||
duplicateStep({ stepId });
|
||||
}}
|
||||
text={t`Duplicate node`}
|
||||
LeftIcon={IconCopyPlus}
|
||||
/>
|
||||
)}
|
||||
{!shouldPinDeleteButton && (
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
closeDropdown(dropdownId);
|
||||
deleteStep(stepId);
|
||||
}}
|
||||
text={t`Delete node`}
|
||||
LeftIcon={IconTrash}
|
||||
/>
|
||||
)}
|
||||
</SelectableList>
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
{stepId !== TRIGGER_STEP_ID && (
|
||||
<SelectableListItem itemId="duplicate" onEnter={handleDuplicateNode}>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'duplicate'}
|
||||
onClick={handleDuplicateNode}
|
||||
text={t`Duplicate node`}
|
||||
LeftIcon={IconCopyPlus}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{!shouldPinDeleteButton && (
|
||||
<SelectableListItem itemId="delete" onEnter={handleDeleteNode}>
|
||||
<MenuItem
|
||||
focused={selectedItemId === 'delete'}
|
||||
onClick={handleDeleteNode}
|
||||
text={t`Delete node`}
|
||||
LeftIcon={IconTrash}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
</OptionsDropdownMenu>
|
||||
);
|
||||
|
||||
const deleteButton = (
|
||||
|
||||
Reference in New Issue
Block a user