Add ActionMenuItem sidebar component

This represents a button wrapped in a form element with customisable action and method attributes
pull/10060/head
Sage Abdullah 2023-01-30 11:17:41 +00:00 zatwierdzone przez Matt Westcott
rodzic b17c72cf3d
commit cf269272be
3 zmienionych plików z 157 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,111 @@
import * as React from 'react';
import Tippy from '@tippyjs/react';
import Icon from '../../Icon/Icon';
import { MenuItemDefinition, MenuItemProps } from './MenuItem';
import { gettext } from '../../../utils/gettext';
import { isDismissed } from '../modules/MainMenu';
import { WAGTAIL_CONFIG } from '../../../config/wagtailConfig';
export const ActionMenuItem: React.FunctionComponent<
MenuItemProps<ActionMenuItemDefinition>
> = ({ item, slim, path, state, dispatch }) => {
const isActive = state.activePath.startsWith(path);
const isInSubMenu = path.split('.').length > 2;
const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
// Do not capture click events with modifier keys or non-main buttons.
if (e.ctrlKey || e.shiftKey || e.metaKey || (e.button && e.button !== 0)) {
return;
}
if (!isDismissed(item, state)) {
dispatch({
type: 'set-dismissible-state',
item,
});
}
};
const className =
'sidebar-menu-item' +
(isActive ? ' sidebar-menu-item--active' : '') +
(isInSubMenu ? ' sidebar-menu-item--in-sub-menu' : '');
return (
<li className={className}>
<Tippy
disabled={!slim || isInSubMenu}
content={item.label}
placement="right"
>
<form {...item.attrs} method={item.method} action={item.action}>
<input
type="hidden"
name="csrfmiddlewaretoken"
value={WAGTAIL_CONFIG.CSRF_TOKEN}
/>
<button
type="submit"
className={`sidebar-menu-item__link ${item.classNames}`}
onClick={onClick}
>
{item.iconName && (
<Icon name={item.iconName} className="icon--menuitem" />
)}
<span className="menuitem">
<span className="menuitem-label">{item.label}</span>
{!isDismissed(item, state) && (
<span className="w-dismissible-badge">
<span className="w-sr-only">{gettext('(New)')}</span>
</span>
)}
</span>
</button>
</form>
</Tippy>
</li>
);
};
export class ActionMenuItemDefinition implements MenuItemDefinition {
name: string;
label: string;
action: string;
attrs: { [key: string]: any };
iconName: string | null;
classNames?: string;
method: string;
constructor({
name,
label,
action,
attrs,
icon_name: iconName = null,
classnames = undefined,
method = 'POST',
}) {
this.name = name;
this.label = label;
this.action = action;
this.attrs = attrs;
this.iconName = iconName;
this.classNames = classnames;
this.method = method;
}
render({ path, slim, state, dispatch, navigate }) {
return (
<ActionMenuItem
key={this.name}
item={this}
path={path}
slim={slim}
state={state}
dispatch={dispatch}
navigate={navigate}
/>
);
}
}

Wyświetl plik

@ -1,4 +1,5 @@
import { initSidebar } from '../../components/Sidebar';
import { ActionMenuItemDefinition } from '../../components/Sidebar/menu/ActionMenuItem';
import { LinkMenuItemDefinition } from '../../components/Sidebar/menu/LinkMenuItem';
import { SubMenuItemDefinition } from '../../components/Sidebar/menu/SubMenuItem';
import { PageExplorerMenuItemDefinition } from '../../components/Sidebar/menu/PageExplorerMenuItem';
@ -7,6 +8,10 @@ import { WagtailBrandingModuleDefinition } from '../../components/Sidebar/module
import { SearchModuleDefinition } from '../../components/Sidebar/modules/Search';
import { MainMenuModuleDefinition } from '../../components/Sidebar/modules/MainMenu';
window.telepath.register(
'wagtail.sidebar.ActionMenuItem',
ActionMenuItemDefinition,
);
window.telepath.register(
'wagtail.sidebar.LinkMenuItem',
LinkMenuItemDefinition,

Wyświetl plik

@ -85,6 +85,47 @@ class LinkMenuItem(MenuItem):
)
@adapter("wagtail.sidebar.ActionMenuItem", base=BaseSidebarAdapter)
class ActionMenuItem(MenuItem):
def __init__(
self,
name: str,
label: str,
action: str,
icon_name: str = "",
classnames: str = "",
method: str = "POST",
attrs: Mapping[str, Any] = None,
):
super().__init__(
name,
label,
icon_name=icon_name,
classnames=classnames,
attrs=attrs,
)
self.action = action
self.method = method
def js_args(self):
args = super().js_args()
args[0]["action"] = self.action
args[0]["method"] = self.method
return args
def __eq__(self, other):
return (
self.__class__ == other.__class__
and self.name == other.name
and self.label == other.label
and self.action == other.action
and self.method == other.method
and self.icon_name == other.icon_name
and self.classnames == other.classnames
and self.attrs == other.attrs
)
@adapter("wagtail.sidebar.SubMenuItem", base=BaseSidebarAdapter)
class SubMenuItem(MenuItem):
def __init__(