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 { useState, Fragment } from 'react';
import { Dropdown, DropdownMenu, MenuItem } from '@wordpress/components'; import { DropdownMenu } from '@wordpress/components';
import { useSelect } from '@wordpress/data'; import { useSelect } from '@wordpress/data';
import { moreVertical, trash } from '@wordpress/icons'; import { moreVertical, trash } from '@wordpress/icons';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { Hooks } from 'wp-js-hooks'; import { Hooks } from 'wp-js-hooks';
import { PremiumModal } from 'common/premium_modal'; import { PremiumModal } from 'common/premium_modal';
import { Step as StepData } from './types'; import { Step as StepData } from './types';
import { storeName } from '../../store'; import { MoreControls, storeName } from '../../store';
type Props = { type Props = {
step: StepData; 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 { export function StepMoreMenu({ step }: Props): JSX.Element {
const { stepType } = useSelect( const { stepType } = useSelect(
(select) => ({ (select) => ({
@@ -30,40 +21,21 @@ export function StepMoreMenu({ step }: Props): JSX.Element {
); );
const [showModal, setShowModal] = useState(false); const [showModal, setShowModal] = useState(false);
const lazyOnClose = () => { const moreControls: MoreControls = Hooks.applyFilters(
currentProps?.onClose();
};
type MoreControls = Record<string, JSX.Element>;
const controls: MoreControls = Hooks.applyFilters(
'mailpoet.automation.workflow.step.more-controls', 'mailpoet.automation.workflow.step.more-controls',
{ {
delete: ( delete: {
<MenuItem key="delete" icon={trash} onClick={() => setShowModal(true)}> key: 'delete',
{__('Delete step', 'mailpoet')} control: {
</MenuItem> title: __('Delete step', 'mailpoet'),
), icon: trash,
onClick: () => setShowModal(true),
}, },
step, slot: () => {
stepType, if (!showModal) {
lazyOnClose, return false;
); }
return ( 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 <PremiumModal
onRequestClose={() => { onRequestClose={() => {
setShowModal(false); setShowModal(false);
@@ -75,7 +47,30 @@ export function StepMoreMenu({ step }: Props): JSX.Element {
> >
{__('You cannot remove a step from the automation.', 'mailpoet')} {__('You cannot remove a step from the automation.', 'mailpoet')}
</PremiumModal> </PremiumModal>
)} );
</> },
},
},
step,
stepType,
);
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 { ComponentType } from 'react';
import { DropdownMenu } from '@wordpress/components';
import { Step, Workflow } from '../components/workflow/types'; import { Step, Workflow } from '../components/workflow/types';
export interface AutomationEditorWindow extends Window { export interface AutomationEditorWindow extends Window {
@@ -61,3 +62,14 @@ export type State = {
}; };
export type Feature = 'fullscreenMode' | 'showIconLabels'; 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>;