Skip to content

Commit

Permalink
Make Menu less dependant on the Kirby instance
Browse files Browse the repository at this point in the history
  • Loading branch information
bastianallgeier committed Feb 7, 2025
1 parent 59348bf commit d95c812
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 123 deletions.
3 changes: 2 additions & 1 deletion src/Panel/Fiber.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ public function menu(): array
$menu = new Menu(
areas: $this->areas,
permissions: $this->permissions,
current: $this->area?->id()
current: $this->area?->id(),
config: $this->kirby->option('panel.menu', null)
);

return $menu->render();
Expand Down
7 changes: 4 additions & 3 deletions src/Panel/Ui/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class Menu extends Component
public function __construct(
array $areas = [],
protected array $permissions = [],
protected string|null $current = null
protected string|null $current = null,
protected Closure|array|null $config = null
) {
foreach ($areas as $area) {
$this->areas[$area->id()] = $area;
Expand Down Expand Up @@ -102,11 +103,11 @@ public function areas(): array
public function config(): array
{
// get from config option which areas should be listed in the menu
$kirby = App::instance();
$items = $kirby->option('panel.menu');
$items = $this->config;

// lazy-load items
if ($items instanceof Closure) {
$kirby = App::instance();
$items = $items($kirby);
}

Expand Down
224 changes: 105 additions & 119 deletions tests/Panel/Ui/MenuTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,12 @@ public function testAreas()
*/
public function testAreasFromMenuOptionWithDivider()
{
$this->app->clone([
'options' => [
'panel' => [
'menu' => [
'-'
]
]
$menu = new Menu(
config: [
'-'
]
]);
);

$menu = new Menu();
$areas = $menu->areas();

$this->assertCount(1, $areas);
Expand All @@ -84,21 +79,16 @@ public function testAreasFromMenuOptionWithDivider()
*/
public function testAreasFromMenuOptionWithUiComponent()
{
$this->app->clone([
'options' => [
'panel' => [
'menu' => [
$menuItem = new MenuItem(
icon: 'test',
text: 'test',
link: 'test'
)
]
]
$menu = new Menu(
config: [
$menuItem = new MenuItem(
icon: 'test',
text: 'test',
link: 'test'
)
]
]);
);

$menu = new Menu();
$areas = $menu->areas();

$this->assertCount(1, $areas);
Expand All @@ -110,19 +100,14 @@ public function testAreasFromMenuOptionWithUiComponent()
*/
public function testAreasFromMenuOptionWithId()
{
$this->app->clone([
'options' => [
'panel' => [
'menu' => [
'site'
]
]
$menu = new Menu(
areas: [
$area = new Area(id: 'site')
],
config: [
'site'
]
]);

$menu = new Menu(areas: [
$area = new Area(id: 'site')
]);
);

$areas = $menu->areas();

Expand All @@ -135,19 +120,14 @@ public function testAreasFromMenuOptionWithId()
*/
public function testAreasFromMenuOptionWithIdKey()
{
$this->app->clone([
'options' => [
'panel' => [
'menu' => [
'site' => true
]
]
$menu = new Menu(
areas: [
$area = new Area(id: 'site')
],
config: [
'site' => true
]
]);

$menu = new Menu(areas: [
$area = new Area(id: 'site')
]);
);

$areas = $menu->areas();

Expand All @@ -160,42 +140,30 @@ public function testAreasFromMenuOptionWithIdKey()
*/
public function testAreasFromMenuOptionWithInvalidId()
{
$this->app->clone([
'options' => [
'panel' => [
'menu' => [
'does-not-exist'
]
]
$menu = new Menu(
config: [
'does-not-exist'
]
]);

$menu = new Menu();
$areas = $menu->areas();
);

$this->assertCount(0, $areas);
$this->assertCount(0, $menu->areas());
}

/**
* @covers ::areas
*/
public function testAreasFromMenuOptionWithArray()
{
$this->app->clone([
'options' => [
'panel' => [
'menu' => [
'site' => [
'icon' => 'edit'
]
]
$menu = new Menu(
areas: [
$area = new Area(id: 'site')
],
config: [
'site' => [
'icon' => 'edit'
]
]
]);

$menu = new Menu(areas: [
$area = new Area(id: 'site')
]);
);

// the area does not have the edit icon by default
$this->assertNotSame('edit', $area->icon());
Expand All @@ -214,20 +182,15 @@ public function testAreasFromMenuOptionWithArray()
*/
public function testAreasFromMenuOptionWithNewArea()
{
$this->app->clone([
'options' => [
'panel' => [
'menu' => [
'todos' => [
'label' => 'Todos',
'link' => 'todos'
]
]
$menu = new Menu(
config: [
'todos' => [
'label' => 'Todos',
'link' => 'todos'
]
]
]);
);

$menu = new Menu();
$areas = $menu->areas();

$this->assertCount(1, $areas);
Expand Down Expand Up @@ -259,19 +222,12 @@ public function testConfig()
public function testConfigWithClosureAndNullAsReturnValue()
{
$test = $this;

$this->app->clone([
'options' => [
'panel' => [
'menu' => function ($kirby) use ($test) {
$test->assertInstanceOf(App::class, $kirby);
return null;
}
]
]
]);

$menu = new Menu();
$menu = new Menu(
config: function ($kirby) use ($test) {
$test->assertInstanceOf(App::class, $kirby);
return null;
}
);

$expected = [
'site',
Expand All @@ -288,17 +244,11 @@ public function testConfigWithClosureAndNullAsReturnValue()
*/
public function testConfigWithClosureAndEmptyArrayAsReturnValue()
{
$this->app->clone([
'options' => [
'panel' => [
'menu' => function () {
return [];
}
]
]
]);

$menu = new Menu();
$menu = new Menu(
config: function () {
return [];
}
);

$this->assertSame([], $menu->config());
}
Expand Down Expand Up @@ -355,29 +305,65 @@ public function testItemWithoutArea()
/**
* @covers ::items
*/
public function testItems()
public function testItemsWithDivider()
{
$menu = new Menu(
areas: [
new Area(
id: 'site',
label: 'Site',
icon: 'home',
menu: true,
link: 'site'
)
'site' => new Area(id: 'site', menu: true),
'system' => new Area(id: 'system', menu: true),
],
current: 'site'
config: [
'site',
'-',
'system',
],
permissions: [
'access' => [
'site' => true,
'system' => true
]
]
);

$items = $menu->items();

$this->assertSame('site', $items[0]['props']['link']);
$this->assertTrue($items[0]['props']['current']);
$this->assertSame('-', $items[1]);
$this->assertSame('changes', $items[2]['props']['dialog']);
$this->assertSame('account', $items[3]['props']['link']);
$this->assertSame('logout', $items[4]['props']['link']);
$this->assertSame('system', $items[2]['props']['link']);
}

/**
* @covers ::items
*/
public function testItemsWithComponent()
{
$menu = new Menu(
areas: [
'site' => new Area(id: 'site', menu: true),
'system' => new Area(id: 'system', menu: true),
],
config: [
'site',
'test' => new MenuItem(
icon: 'test',
text: 'test',
link: 'test'
),
'system',
],
permissions: [
'access' => [
'site' => true,
'system' => true
]
]
);

$items = $menu->items();

$this->assertSame('site', $items[0]['props']['link']);
$this->assertSame('test', $items[1]['props']['link']);
$this->assertSame('system', $items[2]['props']['link']);
}

/**
Expand Down

0 comments on commit d95c812

Please sign in to comment.