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

Customize the navigation menu (resource grouping) #271

Closed
chescos opened this issue Aug 28, 2018 · 27 comments
Closed

Customize the navigation menu (resource grouping) #271

chescos opened this issue Aug 28, 2018 · 27 comments

Comments

@chescos
Copy link

chescos commented Aug 28, 2018

I feel that is it unpractical to just throw all resources under a "Resource" group in the navigation. I have more than 50 resources and it just looks confusing to have them all listed alphabetically under "Resources". I would like to order them into custom groups. Is there currently a way to gain full control of the navigation (e.g through a blade file)?

@albalooshi
Copy link

albalooshi commented Aug 28, 2018

Check out the following file, its contains the blade code navigation menu.
/nova/resources/views/resources/navigation.blade.php

You can easier overriding it and copying it to your resources/views/vendor/nova/resources/ folder.

@chescos
Copy link
Author

chescos commented Aug 28, 2018

@albalooshi thank you! How does it come that you can override it by copying it to resources/views/vendor/nova/resources/, is this an intended way to customize the navigation?

@albalooshi
Copy link

albalooshi commented Aug 28, 2018

@chescos No its not, in case the navigation.blade.php changed after an update and you will need to do the same changes to copied blade file (or you can just make your own navigation blade file).

You can override any package view by creating a file with the same path in resources/views/vendor/<package_name> so this is not related to Nova.

You can close the issue if this solves your problem.

@chescos
Copy link
Author

chescos commented Aug 28, 2018

@albalooshi okay, thank you for explaining! I'll leave this open then, as I hope that it will someday be implemented as a feature (not just a hack).

@antonkomarev
Copy link

Related to #2

@elsodev
Copy link

elsodev commented Sep 4, 2018

Here's a temporary hacky solution until original developers implements a better way of adding resource grouping.

This is my custom navigation.blade.php i copied from original Nova assets to my own assets folder.


@if (count(Nova::availableResources(request())))

    <?php
        $resources_with_parent = collect(Nova::availableResources(request()))->filter(function($resource) {
            return ($resource::$parent);
        })->groupBy(function ($resource) {
            return $resource::$parent;
        });

        $other_resources = collect(Nova::availableResources(request()))->filter(function($resource) {
            return (!$resource::$parent);
        });
    ?>

    @foreach ($resources_with_parent as $parent=>$resources)
        <h3 class="flex items-center font-normal text-white mb-6 text-base no-underline">
            {{ ucwords($parent) }}
        </h3>
        <ul class="list-reset mb-8">
            @foreach ($resources as $resource)
                @if (! $resource::$displayInNavigation)
                    @continue
                @endif

                <li class="leading-wide mb-4 text-sm">
                    <router-link :to="{
                    name: 'index',
                    params: {
                        resourceName: '{{ $resource::uriKey() }}'
                    }
                }" class="text-white ml-8 no-underline dim">
                        {{ $resource::label() }}
                    </router-link>
                </li>
            @endforeach
        </ul>
    @endforeach

    @if(count($other_resources))
        <h3 class="flex items-center font-normal text-white mb-6 text-base no-underline">
            <svg class="sidebar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
                <path fill="var(--sidebar-icon)" d="M3 1h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2H3c-1.1045695 0-2-.8954305-2-2V3c0-1.1045695.8954305-2 2-2zm0 2v4h4V3H3zm10-2h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2h-4c-1.1045695 0-2-.8954305-2-2V3c0-1.1045695.8954305-2 2-2zm0 2v4h4V3h-4zM3 11h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2H3c-1.1045695 0-2-.8954305-2-2v-4c0-1.1045695.8954305-2 2-2zm0 2v4h4v-4H3zm10-2h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2h-4c-1.1045695 0-2-.8954305-2-2v-4c0-1.1045695.8954305-2 2-2zm0 2v4h4v-4h-4z"
                />
            </svg>
            <span class="sidebar-label">{{ __('Resources') }}</span>
        </h3>

        <ul class="list-reset mb-8">
            @foreach ($other_resources as $resource)
                @if (! $resource::$displayInNavigation)
                    @continue
                @endif

                <li class="leading-wide mb-4 text-sm">
                    <router-link :to="{
                    name: 'index',
                    params: {
                        resourceName: '{{ $resource::uriKey() }}'
                    }
                }" class="text-white ml-8 no-underline dim">
                        {{ $resource::label() }}
                    </router-link>
                </li>
            @endforeach
        </ul>
    @endif

@endif

Then in my app\Nova\Resource.php, i added a new static property

public static $parent = null;

Then, for example, I have two Resources under a "Administration" group, so I just set the $parent for each resource classes to "Administration", it will then appear in the navigation under a group.

Other existing resources without any $parent will be displayed normally under "Resources" in the navigation.

What my navigation code does is just splitting up those resources with parents and without parents into two separate collections then loop it out as usual.

@hooch
Copy link

hooch commented Sep 13, 2018

There's also this package @chescos:
https://novapackages.com/packages/alexbowers/nova-categorise-resources

@davidhemphill
Copy link
Contributor

This landed in the release today.

@jochemgruter
Copy link

When will you update the docs to version 1.1 so I now how to implement this?

@dillingham
Copy link
Contributor

@jochemgruter add public static $group = "Group Name"; to your resources

@shalawani
Copy link

@dillingham it doesn't work :(

@alexbowers
Copy link

@shalawani Can you confirm you're on the latest version?

@shalawani
Copy link

image

@alexbowers
Copy link

Can you show some code about how you're trying to group your resources?

It should work, so a code example will help us figure out why it isn't working for you.

@shalawani
Copy link

I just add "public static $group = 'Sellers';" property for my resources

@alexbowers
Copy link

@shalawani Can you show me the composer.json file that you have, if you have any tools or packages being pulled in. So far i'm not able to reproduce it.

@shalawani
Copy link

shalawani commented Oct 1, 2018

@alexbowers

"require": {
    "php": "^7.1.3",
    "bensampo/laravel-enum": "^1.10",
    "chris-ware/nova-clock-card": "^1.0",
    "coreproc/nova-system-info-card": "^0.0.1",
    "cybercog/laravel-nova-ban": "^1.0",
    "davidpiesse/nova-maintenance-mode": "^0.0.3",
    "fideloper/proxy": "^4.0",
    "inspheric/nova-url-field": "^1.1",
    "itsgoingd/clockwork": "^3.0",
    "kabbouchi/nova-impersonate": "dev-master",
    "kabbouchi/nova-logs-tool": "^0.0.3",
    "kalnoy/nestedset": "^4.3",
    "kregel/nova-failed-jobs-tool": "^0.0.4",
    "laravel/framework": "5.7.*",
    "laravel/nova": "~1.0",
    "laravel/tinker": "^1.0",
    "llaski/nova-scheduled-jobs": "^1.1",
    "marianvlad/nova-ssl-card": "^1.0",
    "predis/predis": "^1.1",
    "sbine/route-viewer": "^0.0.3",
    "spatie/laravel-permission": "^2.17",
    "spatie/nova-backup-tool": "^0.1.0",
    "titasgailius/search-relations": "^1.0",
    "vink/nova-cache-card": "^1.0"
  },
  "require-dev": {
    "filp/whoops": "^2.0",
    "fzaninotto/faker": "^1.4",
    "mockery/mockery": "^1.0",
    "nunomaduro/collision": "^2.0",
    "phpunit/phpunit": "^7.0"
  },

@jiker-burce
Copy link

jiker-burce commented Nov 20, 2018

@albalooshi gives me the idea, after copy the file to our resource path, then just to modify the navigation.blade.php like this:

@if (count(Nova::availableResources(request())))
    {{--<h3 class="flex items-center font-normal text-white mb-6 text-base no-underline">--}}
        {{--<svg class="sidebar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">--}}
            {{--<path fill="var(--sidebar-icon)" d="M3 1h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2H3c-1.1045695 0-2-.8954305-2-2V3c0-1.1045695.8954305-2 2-2zm0 2v4h4V3H3zm10-2h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2h-4c-1.1045695 0-2-.8954305-2-2V3c0-1.1045695.8954305-2 2-2zm0 2v4h4V3h-4zM3 11h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2H3c-1.1045695 0-2-.8954305-2-2v-4c0-1.1045695.8954305-2 2-2zm0 2v4h4v-4H3zm10-2h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2h-4c-1.1045695 0-2-.8954305-2-2v-4c0-1.1045695.8954305-2 2-2zm0 2v4h4v-4h-4z"--}}
            {{--/>--}}
        {{--</svg>--}}
        {{--<span class="sidebar-label">{{ __('Resources') }}</span>--}}
    {{--</h3>--}}

    @foreach(Nova::groupedResources(request()) as $group => $resources)
        @if (count($resources) > 0)
            @if (count(Nova::groups(request())) > 1)
                <h3 class="flex items-center font-normal text-white mb-6 text-base no-underline">
                    <svg class="sidebar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
                        <path fill="var(--sidebar-icon)" d="M3 1h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2H3c-1.1045695 0-2-.8954305-2-2V3c0-1.1045695.8954305-2 2-2zm0 2v4h4V3H3zm10-2h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2h-4c-1.1045695 0-2-.8954305-2-2V3c0-1.1045695.8954305-2 2-2zm0 2v4h4V3h-4zM3 11h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2H3c-1.1045695 0-2-.8954305-2-2v-4c0-1.1045695.8954305-2 2-2zm0 2v4h4v-4H3zm10-2h4c1.1045695 0 2 .8954305 2 2v4c0 1.1045695-.8954305 2-2 2h-4c-1.1045695 0-2-.8954305-2-2v-4c0-1.1045695.8954305-2 2-2zm0 2v4h4v-4h-4z"
                        />
                    </svg>

                    <span class="sidebar-label">{{ $group }}</span>

                </h3>
            @endif

            <ul class="list-reset mb-8">
                @foreach($resources as $resource)
                    @if (! $resource::$displayInNavigation)
                        @continue
                    @endif

                    <li class="leading-tight mb-4 ml-8 text-sm">
                        <router-link :to="{
                            name: 'index',
                            params: {
                                resourceName: '{{ $resource::uriKey() }}'
                            }
                        }" class="text-white text-justify no-underline dim">
                            {{ $resource::label() }}
                        </router-link>
                    </li>
                @endforeach
            </ul>
        @endif
    @endforeach
@endif

We'll get very pretty navigation sidebar.
but you should notice to add public static $group = ''; in each resource file.

@mvcexpert
Copy link

I am trying to rename "Resources" sidebar-label in the navagation.blade.php, {{ __('CMS') }} does not reflect the change and still display "Resources". I have tried clearing all caches and views. What is the deal?

@nbejansen
Copy link

nbejansen commented Mar 15, 2020

I've implemented the following solution (which works also with groups):

In resources/views/vendor/nova/resources/navigation.blade.php i've updated the resources menu loop to:

<ul class="list-reset mb-8">
    @php
        $menu = [];
        $noPosStartIndex = 1000;
        foreach($resources as $resource):   
            if(method_exists($resource, 'menuPosition')):
                $menu[$resource::menuPosition()] = $resource;
            else:
                $menu[$noPosStartIndex++] = $resource;
            endif;
        endforeach;
        ksort($menu);
    @endphp
    @foreach($menu as $resource)
        <li class="leading-tight mb-4 ml-8 text-sm">
            <router-link :to="{
                name: 'index',
                params: {
                    resourceName: '{{ $resource::uriKey() }}'
                }
            }" class="text-white text-justify no-underline dim">
                {{ $resource::label() }}
            </router-link>
        </li>
    @endforeach
</ul>

And added a static menuPosition() function to each resource:

/**
* Returns the menu position.
*
* @return int
*/
public static function menuPosition()
{
    return 10;
}

@p0ntsNL
Copy link

p0ntsNL commented Apr 2, 2020

sorry for the bump, but would it also be possible to get rid of the "resources" main menu and put all the resources in their own menu item like the Dashboard?

@xerox-xeon
Copy link

I just add "public static $group = 'Sellers';" property for my resources

which path?

@xerox-xeon
Copy link

@jochemgruter add public static $group = "Group Name"; to your resources

which class file?

@mouadziani
Copy link

@LifeBlood At any resource class

@nicko170
Copy link

nicko170 commented Jul 6, 2021

sorry for the bump, but would it also be possible to get rid of the "resources" main menu and put all the resources in their own menu item like the Dashboard?

hey @p0nt - I just did that today.

Screen Shot 2021-07-07 at 8 01 04 am

In each resource, set a group

    /**
     * The logical group associated with the resource.
     *
     * @var string
     */
    public static $group = 'Accounts';

Then we can copy the file from Nova, and edit the loop that displays the menu.
cp vendor/laravel/nova/resources/views/resources/navigation.blade.php resources/views/vendor/nova/resources

edit resources/views/vendor/nova/resources/navigation.blade.php

Then something like this - note, mix and match the icons from heroicons.

@if (count(\Laravel\Nova\Nova::resourcesForNavigation(request())))
    @foreach($navigation as $group => $resources)
        <h3 class="flex items-center font-normal text-white mb-6 text-base no-underline">
            @if($group === 'Accounts')
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="sidebar-icon"
                     stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                          d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
                </svg>
            @elseif($group === 'Network')
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="sidebar-icon"
                     stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                          d="M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0"/>
                </svg>
            @endif
            <span class="sidebar-label">{{ $group }}</span>
        </h3>

        <ul class="list-reset mb-8">
            @foreach($resources as $resource)
                <li class="leading-tight mb-4 ml-8 text-sm">
                    <router-link :to="{
                        name: 'index',
                        params: {
                            resourceName: '{{ $resource::uriKey() }}'
                        }
                    }" class="text-white text-justify no-underline dim" dusk="{{ $resource::uriKey() }}-resource-link">
                        {{ $resource::label() }}
                    </router-link>
                </li>
            @endforeach
        </ul>
    @endforeach
@endif

@Arturexe
Copy link

@nicko170 Hey, I've tried your approach but editing the navigation.blade.php does not change anything. Do I have to make additional changes to Nova?

@nicko170
Copy link

Hey @Arturexe

I stopped doing it that way - check this package out.

https://github.com/dcasia/collapsible-resource-manager

You have to remember to add each resource in when you creat new ones - it's no longer automatic, but it's absolutely amazing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests