maelstrom-cms / toolkit

A CMS Toolkit built on Laravel and React
https://www.maelstrom-cms.com
61 stars 6 forks source link

Submenu items not remaining open when they should [Bug] #5

Closed jackcaspers closed 4 years ago

jackcaspers commented 4 years ago

Describe the bug If there are nested submenus and you select a Link at the lowest submenu, some of the nested submenus will not remain open if they do not have a url associated with them. In my case, I have it set up with Submenu     Submenu         Submenu             Link When I click on the Link, the only Submenu that remains open is the last one.

To Reproduce This is what I used to create a test sidebar which reproduced the issue.

     [
                'type' => 'SubMenu',
                'id' => 'admin_user_menu',
                'label' => 'Users',
                'icon' => 'user',
                'children' => [
                    [
                        'type' => 'SubMenu',
                        'id' => 'test_menu_1',
                        'label' => 'test 1',
                        'icon' => 'folder',
                        'children' => [
                            [
                                'type' => 'SubMenu',
                                'id' => 'test_menu_2',
                                'label' => 'test 2',
                                'icon' => 'folder',
                                'children' => [
                                    [
                                        'type' => 'Link',
                                        'id' => 'user_add',
                                        'url' => '/admin/users/create/',
                                        'label' => 'Add User',
                                        'icon' => 'user-add',
                                    ],
                                ],
                            ]
                        ],
                    ],
                ],
            ],

Expected behavior All submenus submenus should remain open instead of just the last submenu. I believe the issue is with Sidebar.js component in the source code. I believe the main problem is with this condition

if (
            this.guessSelected &&
            itemUrl &&
            item.selected !== false &&
            window.location.toString().indexOf(itemUrl) !== -1
        ) {

The Submenu items do not have a url associated with them so they never pass this condition and are never added to this.defaultOpenKeys when they should. However, the last submenu will get added because it is the parent of the selected Link.

It is entirely possible I missed something so if I did please let me know. I will also provide more clarification if necessary.

OwenMelbz commented 4 years ago

Hi,

I'll have a look to see if theres a way to automate this.

However theres a couple of was you can do it already.

Option 1

It works on URL nesting for automation, so you can trick it by passing a url to each parent component which will make it think it belongs to it. Below is a reduced example

$sidebar = [
    'type' => 'SubMenu',
    'url' => '/admin/users',
    //....
    'children' => [
        [
            'type' => 'SubMenu',
            'url' => '/admin/users',
            //....
            'children' => [
                [
                    'type' => 'SubMenu',
                    'url' => '/admin/users',
                    //....
                    'children' => [
                        [
                            'type' => 'Link',
                            'url' => '/admin/users/create/',
                        ],
                    ],
                ]
            ],
        ],
    ],
];

So when you're on /admin/users/create/ it will select the parents as they have /admin/users in their url props.

Option 2

As the JS is disconnected from your Laravel application itself, it doesn't know what your structure is or which menu needs to be opened, it can only "guess". But you can explicitly tell it which ones are open yourself.

$sidebar = [
    'type' => 'SubMenu',
    'selected' => true,
    //....
    'children' => [
        [
            'type' => 'SubMenu',
            'selected' => true,
            //....
            'children' => [
                [
                    'type' => 'SubMenu',
                    'selected' => true,
                    //....
                    'children' => [
                        [
                            'type' => 'Link',
                            'url' => '/admin/users/create/',
                        ],
                    ],
                ]
            ],
        ],
    ],
];

You can utilise this with the laravel request helpers, e.g.

'selected' => request()->is('admin/users/*')

I did find a bug with this though, that meant SubMenu and submenu would not be compatible, so I've released a bugfix for that as version 1.0.41 to make the selected work with SubMenu