Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Isolate Drawer menu from the rest of the UI #3773

Draft
wants to merge 22 commits into
base: 9.0
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c573752
!!!TASK: Split `user` key from `initialData` via separate `UserProvider`
grebaldi Apr 30, 2024
6b2ab97
TASK: Convert `<UserImage/>` container to typescript
grebaldi Apr 30, 2024
9bd2d84
TASK: Convert `<RestoreButtonItem/>` container to typescript
grebaldi Apr 30, 2024
82c2bb2
TASK: Convert `<UserDropDown/>` container to typescript
grebaldi Apr 30, 2024
f91d89a
PATCH: Fix typing in UserProviderInterface
grebaldi May 21, 2024
9aa6548
TASK: Convert parsing of initial data to Typescript
grebaldi May 21, 2024
6b8b823
TASK: Make `alias`optional in `initializeJsAPI`
grebaldi May 21, 2024
f65f3cb
TASK: Detach user menu from redux store
grebaldi May 21, 2024
428eb0a
BUGFIX: Render dropdown contents even when dropdown is closed
grebaldi May 30, 2024
0d1d8d4
TASK: Convert VersionPanel component to typescript
grebaldi May 30, 2024
69056eb
TASK: Convert Drawer/constants to typescript
grebaldi May 30, 2024
0a7ee42
TASK: Convert Drawer/MenuItem component to typescript
grebaldi May 30, 2024
9f2cd25
TASK: Convert Drawer/MenuItemGroup to typescript
grebaldi May 30, 2024
c230da3
TASK: Convert Drawer component to typescript
grebaldi May 30, 2024
5328db4
PATCH: Don't pass user down to Drawer & UserDropDown
grebaldi May 30, 2024
f38ef47
PATCH: Move impersonateRestore out of the redux store
grebaldi May 30, 2024
f713159
PATCH: Move impersonateRestore out of the redux store part II
grebaldi Jun 13, 2024
50bedad
TASK: Remove unused `target` property from drawer menu items
grebaldi Jun 13, 2024
75ecb7a
TASK: Convert MenuToggler to typescript
grebaldi Jun 14, 2024
7e04b2a
TASK: Decouple Drawer from redux store
grebaldi Jun 14, 2024
1023f8e
TASK: Followup c6b138396593cee9bff5f077784558ee33cbdde3
mhsdesign Jan 14, 2025
d1f2456
TASK: Make linting happy for now
mhsdesign Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
TASK: Remove unused target property from drawer menu items
grebaldi authored and mhsdesign committed Jan 15, 2025
commit 50bedadcfdb27edcb9a0951e79ce5bcfc0bb9e97
3 changes: 0 additions & 3 deletions Classes/Infrastructure/Neos/MenuProvider.php
Original file line number Diff line number Diff line change
@@ -55,7 +55,6 @@ public function getMenu(ActionRequest $actionRequest): array
$result[$moduleName]['label'] = $module['label'];
$result[$moduleName]['icon'] = $module['icon'];
$result[$moduleName]['uri'] = $module['uri'];
$result[$moduleName]['target'] = 'Window';

$result[$moduleName]['children'] = match ($module['module']) {
'content' => $this->buildChildrenForSites($controllerContext),
@@ -89,7 +88,6 @@ private function buildChildrenForSites(ControllerContext $controllerContext): ar
$result[$index]['icon'] = 'globe';
$result[$index]['label'] = $name;
$result[$index]['uri'] = $uri;
$result[$index]['target'] = 'Window';
$result[$index]['isActive'] = $active;
$result[$index]['skipI18n'] = true;
}
@@ -114,7 +112,6 @@ private function buildChildrenForBackendModule(array $module): array
$result[$submoduleName]['uri'] = $submodule['uri'];
$result[$submoduleName]['position'] = $submodule['position'];
$result[$submoduleName]['isActive'] = true;
$result[$submoduleName]['target'] = 'Window';
$result[$submoduleName]['skipI18n'] = false;
}

30 changes: 3 additions & 27 deletions packages/neos-ui/src/Containers/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -19,15 +19,14 @@ import {SynchronousRegistry} from '@neos-project/neos-ui-extensibility';

import MenuItemGroup from './MenuItemGroup/index';
import style from './style.module.css';
import {TARGET_WINDOW, TARGET_CONTENT_CANVAS, THRESHOLD_MOUSE_LEAVE} from './constants';
import {THRESHOLD_MOUSE_LEAVE} from './constants';

const withReduxState = connect((state: GlobalState) => ({
isHidden: state?.ui?.drawer?.isHidden,
collapsedMenuGroups: state?.ui?.drawer?.collapsedMenuGroups
}), {
hideDrawer: actions.UI.Drawer.hide,
toggleMenuGroup: actions.UI.Drawer.toggleMenuGroup,
setContentCanvasSrc: actions.UI.ContentCanvas.setSrc
toggleMenuGroup: actions.UI.Drawer.toggleMenuGroup
});

const withNeosGlobals = neos(globalRegistry => ({
@@ -40,7 +39,6 @@ const StatelessDrawer: React.FC<{

hideDrawer: () => void;
toggleMenuGroup: (menuGroup: string) => void;
setContentCanvasSrc: (src: string) => void;

containerRegistry: SynchronousRegistry<any>;

@@ -54,7 +52,6 @@ const StatelessDrawer: React.FC<{
icon?: string;
label: string;
uri?: string;
target?: string;
isActive: boolean;
skipI18n: boolean;
}[];
@@ -75,25 +72,6 @@ const StatelessDrawer: React.FC<{
}, THRESHOLD_MOUSE_LEAVE);
}
}, [props.hideDrawer]);
const handleMenuItemClick = React.useCallback((target?: string, uri?: string) => {
const {setContentCanvasSrc, hideDrawer} = props;

switch (target) {
case TARGET_CONTENT_CANVAS:
if (uri) {
setContentCanvasSrc(uri);
}
hideDrawer();
break;

case TARGET_WINDOW:
default:
// we do not need to do anything here, as MenuItems of type TARGET_WINDOW automatically
// wrap their contents in an <a>-tag (such that the user can crtl-click it to open in a
// new window).
break;
}
}, [props.setContentCanvasSrc, props.hideDrawer]);
const {isHidden, menuData, collapsedMenuGroups, toggleMenuGroup, containerRegistry} = props;
const classNames = mergeClassNames({
[style.drawer]: true,
@@ -110,11 +88,9 @@ const StatelessDrawer: React.FC<{
aria-hidden={isHidden ? 'true' : 'false'}
>
<div className={style.drawer__menuItemGroupsWrapper}>
{!isHidden && Object.entries(menuData).map(([menuGroup, menuGroupConfiguration]) => (
{Object.entries(menuData).map(([menuGroup, menuGroupConfiguration]) => (
<MenuItemGroup
key={menuGroup}
onClick={handleMenuItemClick}
onChildClick={handleMenuItemClick}
collapsed={Boolean(collapsedMenuGroups.includes(menuGroup))}
handleMenuGroupToggle={() => toggleMenuGroup(menuGroup)}
{...menuGroupConfiguration}
42 changes: 14 additions & 28 deletions packages/neos-ui/src/Containers/Drawer/MenuItem/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -14,41 +14,27 @@ import {Icon, Button} from '@neos-project/react-ui-components';
import I18n from '@neos-project/neos-ui-i18n';

import style from '../style.module.css';
import {TARGET_WINDOW} from '../constants';

export const MenuItem: React.FC<{
icon?: string;
label: string;
uri?: string;
target?: string;
isActive: boolean;
skipI18n?: boolean;

onClick: (target?: string, uri?: string) => void;
}> = (props) => {
const handleClick = React.useCallback(() => {
const {uri, target, onClick} = props;

onClick(target, uri);
}, [props.onClick, props.uri, props.target]);

const {skipI18n, label, icon, uri, target} = props;

const button = (
<Button
className={style.drawer__menuItemBtn}
onClick={handleClick}
style="transparent"
hoverStyle="clean"
disabled={!uri}
>
{icon && <Icon icon={icon} padded="right"/>}
{skipI18n ? label : <I18n id={label} fallback={label}/>}
</Button>
const {skipI18n, label, icon, uri} = props;

return (
<a href={uri}>
<Button
className={style.drawer__menuItemBtn}
style="transparent"
hoverStyle="clean"
disabled={!uri}
>
{icon && <Icon icon={icon} padded="right"/>}
{skipI18n ? label : <I18n id={label} fallback={label}/>}
</Button>
</a>
);

if (target === TARGET_WINDOW) {
return <a href={uri}>{button}</a>;
}
return button;
}
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ import {Icon, ToggablePanel, Button} from '@neos-project/react-ui-components';
import I18n from '@neos-project/neos-ui-i18n';

import MenuItem from '../MenuItem/index';
import {TARGET_WINDOW} from '../constants';
import style from '../style.module.css';

export const MenuItemGroup: React.FC<{
@@ -28,44 +27,30 @@ export const MenuItemGroup: React.FC<{
icon?: string;
label: string;
uri?: string;
target?: string;
isActive: boolean;
skipI18n?: boolean;
}[];

onClick: (target?: string, uri?: string) => void;
onChildClick: () => void;
}> = (props) => {
const handleClick = React.useCallback(() => {
const {uri, target, onClick} = props;

onClick(target, uri);
}, [props.onClick, props.target, props.uri]);
const {label, icon, children, onChildClick, target, uri, collapsed, handleMenuGroupToggle} = props;

const headerButton = (
<Button
className={style.drawer__menuItemGroupBtn}
onClick={handleClick}
style="transparent"
hoverStyle="clean"
>
{icon && <Icon icon={icon} padded="right"/>}

<I18n id={label} fallback={label}/>
</Button>
);

const header = (target === TARGET_WINDOW ? <a href={uri}>{headerButton}</a> : headerButton);
const {label, icon, children, uri, collapsed, handleMenuGroupToggle} = props;

return (
<ToggablePanel onPanelToggle={handleMenuGroupToggle} isOpen={!collapsed} style="condensed" className={style.drawer__menuItem}>
<ToggablePanel.Header className={style.drawer__menuItem__header}>
{header}
<a href={uri}>
<Button
className={style.drawer__menuItemGroupBtn}
style="transparent"
hoverStyle="clean"
>
{icon && <Icon icon={icon} padded="right"/>}

<I18n id={label} fallback={label}/>
</Button>
</a>
</ToggablePanel.Header>
<ToggablePanel.Contents>
{children.map((item, index) => (
<MenuItem key={index} onClick={onChildClick} {...item}/>
<MenuItem key={index} {...item}/>
))}
</ToggablePanel.Contents>
</ToggablePanel>
2 changes: 0 additions & 2 deletions packages/neos-ui/src/Containers/Drawer/constants.ts
Original file line number Diff line number Diff line change
@@ -7,6 +7,4 @@
* information, please view the LICENSE file which was distributed with this
* source code.
*/
export const TARGET_WINDOW = 'Window';
export const TARGET_CONTENT_CANVAS = 'ContentCanvas';
export const THRESHOLD_MOUSE_LEAVE = 500;