Skip to content

Commit

Permalink
Allow Entity class name in Sharp's menu + document as new default + t…
Browse files Browse the repository at this point in the history
…ests
  • Loading branch information
dvlpp committed Feb 6, 2025
1 parent 796875c commit f7cb2ae
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 25 deletions.
18 changes: 12 additions & 6 deletions demo/app/Sharp/SharpMenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

namespace App\Sharp;

use App\Sharp\Entities\AuthorEntity;
use App\Sharp\Entities\CategoryEntity;
use App\Sharp\Entities\DemoDashboardEntity;
use App\Sharp\Entities\PostEntity;
use App\Sharp\Entities\ProfileEntity;
use App\Sharp\Entities\TestEntity;
use Code16\Sharp\Utils\Menu\SharpMenu as BaseSharpMenu;
use Code16\Sharp\Utils\Menu\SharpMenuItemSection;
use Code16\Sharp\Utils\Menu\SharpMenuUserMenu;
Expand All @@ -13,17 +19,17 @@ public function build(): self
return $this
->setUserMenu(function (SharpMenuUserMenu $userMenu) {
$userMenu
->addEntityLink('profile', 'Profile')
->addEntityLink(ProfileEntity::class, 'Profile')
->addExternalLink('https://sharp.code16.fr/docs', 'Documentation');
})
->addSection('Blog', function (SharpMenuItemSection $section) {
$section
->setCollapsible(false)
->addEntityLink('posts', 'Posts', icon: 'far-file')
->addEntityLink('categories', 'Categories', icon: 'fas-sitemap')
->addEntityLink('authors', 'Authors', icon: 'far-user');
->addEntityLink(PostEntity::class, 'Posts', icon: 'far-file')
->addEntityLink(CategoryEntity::class, 'Categories', icon: 'fas-sitemap')
->addEntityLink(AuthorEntity::class, 'Authors', icon: 'far-user');
})
->addEntityLink('dashboard', 'Dashboard', icon: 'fas-chart-line')
->addEntityLink('test', 'Fields test', icon: 'fas-cog');
->addEntityLink(DemoDashboardEntity::class, 'Dashboard', icon: 'fas-chart-line')
->addEntityLink(TestEntity::class, 'Fields test', icon: 'fas-cog');
}
}
32 changes: 16 additions & 16 deletions docs/guide/building-menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class SharpServiceProvider extends SharpAppServiceProvider
{
$config
->setSharpMenu(MySharpMenu::class)
// [...]
// ...
}
}
```
Expand All @@ -52,13 +52,13 @@ class MySharpMenu extends Code16\Sharp\Utils\Menu\SharpMenu
public function build(): self
{
return $this
->addEntityLink('post', 'Posts')
->addEntityLink('category', 'Categories');
->addEntityLink(PostEntity::class, 'Posts')
->addEntityLink(CategoryEntity::class, 'Categories');
}
}
```

In this example, "post" and "category" should be entities defined in the config file. Sharp will create a link either to the Entity List, to the Dashboard or to a [single Show Page](single-show.md) (depending on the entity configuration).
In this example, `PostEntity::class` and `CategoryEntity::class` should be `SharpEntity` classes declared in Sharp’s configuration. Sharp will create a link either to the Entity List, to the Dashboard or to a [single Show Page](single-show.md) (depending on the entity configuration).

### Link to an external URL

Expand All @@ -82,8 +82,8 @@ class MySharpMenu extends Code16\Sharp\Utils\Menu\SharpMenu
public function build(): self
{
return $this
->addEntityLink('post', 'Posts', icon: 'fas-file')
->addEntityLink('directory', 'Directories', icon: 'heroicon-o-folder')
->addEntityLink(PostEntity::class, 'Posts', icon: 'fas-file')
->addEntityLink(DirectoryEntity::class, 'Directories', icon: 'heroicon-o-folder')
->addExternalLink('https://example.org', 'Homepage', icon: 'icon-logo'); // icon defined in the project (e.g. in resources/svg)
}
}
Expand All @@ -99,10 +99,10 @@ class MySharpMenu extends Code16\Sharp\Utils\Menu\SharpMenu
public function build(): self
{
return $this
->addSection('Admin', function(SharpMenuItemSection $section) {
->addSection('Admin', function (SharpMenuItemSection $section) {
$section
->addEntityLink('account', 'My account')
->addEntityLink('user', 'Sharp users');
->addEntityLink(AccountEntity::class, 'My account')
->addEntityLink(UserEntity::class, 'Sharp users');
});
}
}
Expand All @@ -118,11 +118,11 @@ class MySharpMenu extends Code16\Sharp\Utils\Menu\SharpMenu
public function build(): self
{
return $this
->addSection('Admin', function(SharpMenuItemSection $section) {
->addSection('Admin', function (SharpMenuItemSection $section) {
$section
->addEntityLink('account', 'My account')
->addEntityLink(AccountEntity::class, 'My account')
->addSeparator('Other users')
->addEntityLink('user', 'Sharp users');
->addEntityLink(UserEntity::class, 'Sharp users');
});
}
}
Expand All @@ -138,10 +138,10 @@ class MySharpMenu extends Code16\Sharp\Utils\Menu\SharpMenu
public function build(): self
{
return $this
->addSection('Admin', function(SharpMenuItemSection $section) {
->addSection('Admin', function (SharpMenuItemSection $section) {
$section
->setCollapsible(false)
->addEntityLink('account', 'My account');
->addEntityLink(AccountEntity::class, 'My account');
});
}
}
Expand All @@ -158,7 +158,7 @@ class MySharpMenu extends Code16\Sharp\Utils\Menu\SharpMenu
{
return $this
->setVisible(auth()->user()->isAdmin())
->addSection(...);
->addSection(/*...*/);
}
}
```
Expand All @@ -174,7 +174,7 @@ class MySharpMenu extends Code16\Sharp\Utils\Menu\SharpMenu
{
return $this
->setUserMenu(function (SharpMenuUserMenu $menu) {
$menu->addEntityLink('account', 'My account');
$menu->addEntityLink(AccountEntity::class, 'My account');
});
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/Utils/Menu/HasSharpMenuItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@

namespace Code16\Sharp\Utils\Menu;

use Code16\Sharp\Utils\Entities\SharpEntityManager;

trait HasSharpMenuItems
{
protected array $items = [];

public function addEntityLink(string $entityKey, ?string $label = null, ?string $icon = null): self
public function addEntityLink(string $entityKeyOrClassName, ?string $label = null, ?string $icon = null): self
{
$this->items[] = (new SharpMenuItemLink($label, $icon))->setEntity($entityKey);
if (class_exists($entityKeyOrClassName)) {
$entityKeyOrClassName = app(SharpEntityManager::class)
->entityKeyFor($entityKeyOrClassName);
}

$this->items[] = (new SharpMenuItemLink($label, $icon))
->setEntity($entityKeyOrClassName);

return $this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Utils/Menu/SharpMenuItemLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function isEntity(): bool
return $this->entityKey !== null;
}

public function getEntityKey(): string
public function getEntityKey(): ?string
{
return $this->entityKey;
}
Expand Down
105 changes: 105 additions & 0 deletions tests/Unit/Utils/SharpMenuTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

use Code16\Sharp\Tests\Fixtures\Entities\PersonEntity;
use Code16\Sharp\Utils\Menu\SharpMenu;

it('allows to add an entity link with its key in the menu', function () {
sharp()->config()->addEntity('my-entity', PersonEntity::class);

$menu = new class() extends SharpMenu
{
public function build(): SharpMenu
{
return $this->addEntityLink('my-entity', 'test', 'fa-user');
}
};

expect($menu->build()->getItems()[0])
->getLabel()->toEqual('test')
->getIcon()->toEqual('fa-user')
->isEntity()->toBeTrue()
->getEntityKey()->toEqual('my-entity')
->getUrl()->toEqual(route('code16.sharp.list', 'my-entity'));
});

it('allows to add an entity link with its entity class name in the menu', function () {
sharp()->config()->addEntity('my-entity', PersonEntity::class);

$menu = new class() extends SharpMenu
{
public function build(): SharpMenu
{
return $this->addEntityLink(PersonEntity::class, 'test', 'fa-user');
}
};

expect($menu->build()->getItems()[0])
->getLabel()->toEqual('test')
->getIcon()->toEqual('fa-user')
->isEntity()->toBeTrue()
->getEntityKey()->toEqual('my-entity')
->getUrl()->toEqual(route('code16.sharp.list', 'my-entity'));
});

it('allows to add an external link in the menu', function () {
$menu = new class() extends SharpMenu
{
public function build(): SharpMenu
{
return $this->addExternalLink('https://code16.fr', 'test', 'fa-link');
}
};

expect($menu->build()->getItems()[0])
->getLabel()->toEqual('test')
->getIcon()->toEqual('fa-link')
->isExternalLink()->toBeTrue()
->getEntityKey()->toBeNull()
->getUrl()->toEqual('https://code16.fr');
});

it('allows to group links in sections', function () {
sharp()->config()->addEntity('my-entity', PersonEntity::class);

$menu = new class() extends SharpMenu
{
public function build(): SharpMenu
{
return $this->addSection(
'my section',
fn ($section) => $section->addEntityLink('my-entity', 'test', 'fa-user')
);
}
};

expect($menu->build()->getItems()[0])
->getLabel()->toEqual('my section')
->isSection()->toBeTrue()
->isCollapsible()->toBeTrue()
->getItems()->toHaveCount(1);
});

it('allows to make collapsible / non-collapsible sections', function () {
$menu = new class() extends SharpMenu
{
public function build(): SharpMenu
{
return $this
->addSection(
'my first section',
fn ($section) => $section
->addExternalLink('https://code16.fr', 'test')
)
->addSection(
'my second section',
fn ($section) => $section
->setCollapsible(false)
->addExternalLink('https://code16.fr', 'test')
);
}
};

expect($menu->build()->getItems())->toHaveCount(2);
expect($menu->build()->getItems()[0]->isCollapsible())->toBeTrue();
expect($menu->build()->getItems()[1]->isCollapsible())->toBeFalse();
});

0 comments on commit f7cb2ae

Please sign in to comment.