Use controls property of DropdownMenu

[MAILPOET-4674]
This commit is contained in:
David Remer
2022-11-01 09:48:05 +02:00
committed by Jan Jakeš
parent 2d0673a864
commit 1b59b95f52
2 changed files with 59 additions and 52 deletions

View File

@@ -1,26 +1,17 @@
import { useState } from 'react';
import { Dropdown, DropdownMenu, MenuItem } from '@wordpress/components';
import { useState, Fragment } from 'react';
import { DropdownMenu } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { moreVertical, trash } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { Hooks } from 'wp-js-hooks';
import { PremiumModal } from 'common/premium_modal';
import { Step as StepData } from './types';
import { storeName } from '../../store';
import { MoreControls, storeName } from '../../store';
type Props = {
step: StepData;
};
// I do not like this hack.
// What I want to achieve: With the lazyOnClose method, I want to be able to control to close
// the menu from within a menuitem.
// But there must be a better way then storing currentProps like that.
let currentProps: Dropdown.RenderProps | null = null;
function setCurrentProps(current) {
currentProps = current;
}
export function StepMoreMenu({ step }: Props): JSX.Element {
const { stepType } = useSelect(
(select) => ({
@@ -30,52 +21,56 @@ export function StepMoreMenu({ step }: Props): JSX.Element {
);
const [showModal, setShowModal] = useState(false);
const lazyOnClose = () => {
currentProps?.onClose();
};
type MoreControls = Record<string, JSX.Element>;
const controls: MoreControls = Hooks.applyFilters(
const moreControls: MoreControls = Hooks.applyFilters(
'mailpoet.automation.workflow.step.more-controls',
{
delete: (
<MenuItem key="delete" icon={trash} onClick={() => setShowModal(true)}>
{__('Delete step', 'mailpoet')}
</MenuItem>
),
delete: {
key: 'delete',
control: {
title: __('Delete step', 'mailpoet'),
icon: trash,
onClick: () => setShowModal(true),
},
slot: () => {
if (!showModal) {
return false;
}
return (
<PremiumModal
onRequestClose={() => {
setShowModal(false);
}}
tracking={{
utm_medium: 'upsell_modal',
utm_campaign: 'remove_automation_step',
}}
>
{__('You cannot remove a step from the automation.', 'mailpoet')}
</PremiumModal>
);
},
},
},
step,
stepType,
lazyOnClose,
);
return (
<>
<div className="mailpoet-automation-step-more-menu">
<DropdownMenu
label={__('More', 'mailpoet')}
icon={moreVertical}
popoverProps={{ position: 'bottom right' }}
toggleProps={{ isSmall: true }}
>
{(props) => {
setCurrentProps(props);
return <>{Object.values(controls)}</>;
}}
</DropdownMenu>
</div>
{showModal && (
<PremiumModal
onRequestClose={() => {
setShowModal(false);
}}
tracking={{
utm_medium: 'upsell_modal',
utm_campaign: 'remove_automation_step',
}}
>
{__('You cannot remove a step from the automation.', 'mailpoet')}
</PremiumModal>
)}
</>
const slots = Object.values(moreControls).filter(
(item) => item.slot !== undefined,
);
const controls = Object.values(moreControls).map((item) => item.control);
return (
<div className="mailpoet-automation-step-more-menu">
{slots.map(({ key, slot }) => (
<Fragment key={key}>{slot()}</Fragment>
))}
<DropdownMenu
label={__('More', 'mailpoet')}
icon={moreVertical}
popoverProps={{ position: 'bottom right' }}
toggleProps={{ isSmall: true }}
controls={Object.values(controls)}
/>
</div>
);
}

View File

@@ -1,4 +1,5 @@
import { ComponentType } from 'react';
import { DropdownMenu } from '@wordpress/components';
import { Step, Workflow } from '../components/workflow/types';
export interface AutomationEditorWindow extends Window {
@@ -61,3 +62,14 @@ export type State = {
};
export type Feature = 'fullscreenMode' | 'showIconLabels';
export type MoreControl = {
key: string;
control: DropdownMenu.Control;
slot: () => JSX.Element | undefined;
};
/**
* Used in the "mailpoet.automation.workflow.step.more-controls" filter
*/
export type MoreControls = Record<string, MoreControl>;