Skip to content

Commit

Permalink
[4.x] Add helper arg for addons to easily remove child item in core n…
Browse files Browse the repository at this point in the history
…av (#8883)
  • Loading branch information
jesseleite authored Nov 1, 2023
1 parent 6a540f3 commit 366ff26
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 5 deletions.
49 changes: 45 additions & 4 deletions src/CP/Navigation/Nav.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,31 +45,49 @@ public function item($name)
}

/**
* Find or create nav item.
* Find nav item.
*
* @param string $section
* @param string $name
* @return NavItem|null
*/
public function findOrCreate($section, $name)
public function find($section, $name)
{
$item = collect($this->items)->first(function ($item) use ($section, $name) {
return $item->section() === $section
&& $item->display() === $name
&& ! $item->isChild();
});

return $item ?: $this->create($name)->section($section);
return $item;
}

/**
* Find or create nav item.
*
* @param string $section
* @param string $name
* @return NavItem
*/
public function findOrCreate($section, $name)
{
return $this->find($section, $name) ?: $this->create($name)->section($section);
}

/**
* Remove nav item.
*
* @param string $section
* @param string|null $name
* @param string|null $childName
* @return $this
*/
public function remove($section, $name = null)
public function remove($section, $name = null, $childName = null)
{
if ($childName) {
return $this->removeChildItem($section, $name, $childName);
}

$this->items = collect($this->items)
->reject(function ($item) use ($section, $name) {
return $name
Expand All @@ -81,6 +99,29 @@ public function remove($section, $name = null)
return $this;
}

/**
* Remove nav item.
*
* @param string $section
* @param string|null $name
* @param string|null $childName
* @return $this
*/
protected function removeChildItem($section, $name, $childName)
{
if (! $parent = $this->find($section, $name)) {
return $this;
}

if (! $children = $parent->resolveChildren()->children()) {
return $this;
}

$parent->children($children->reject(fn ($child) => $child->display() === $childName));

return $this;
}

/**
* Build navigation.
*
Expand Down
85 changes: 84 additions & 1 deletion tests/CP/Navigation/NavTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,35 @@ public function it_can_create_a_nav_item_with_a_custom_svg_icon()
}

/** @test */
public function it_can_get_and_modify_an_existing_item()
public function it_can_find_and_modify_an_existing_item()
{
$this->actingAs(tap(User::make()->makeSuper())->save());

Nav::droids('WAC-47')
->url('/pit-droid')
->icon('<svg>...</svg>');

Nav::find('Droids', 'WAC-47')
->url('/d-squad');

$item = $this->build()->get('Droids')->first();

$this->assertEquals('Droids', $item->section());
$this->assertEquals('WAC-47', $item->display());
$this->assertEquals('<svg>...</svg>', $item->icon());
$this->assertEquals('http://localhost/d-squad', $item->url());
}

/** @test */
public function it_can_find_and_modify_an_existing_item_using_magic_constructor()
{
$this->actingAs(tap(User::make()->makeSuper())->save());

Nav::droids('WAC-47')
->url('/pit-droid')
->icon('<svg>...</svg>');

// Callign the same constructor does a `findOrCreate()` under the hood...
Nav::droids('WAC-47')
->url('/d-squad');

Expand Down Expand Up @@ -344,6 +365,41 @@ public function it_can_remove_a_specific_nav_item()
$this->assertEquals('A-Wing', $ships->first()->display());
}

/** @test */
public function it_can_remove_a_specific_nav_child_item()
{
$this->actingAs(tap(User::make()->makeSuper())->save());

Nav::ships('Y-Wing')
->url('/y-wing')
->icon('y-wing')
->children(function () {
return [
Nav::item('Foo'),
Nav::item('Bar'),
];
});

Nav::ships('A-Wing')
->url('/a-wing')
->icon('a-wing')
->children(function () {
return [
Nav::item('Foo'),
Nav::item('Bar'),
];
});

$this->assertCount(2, $this->build()->get('Ships'));

Nav::remove('Ships', 'Y-Wing', 'Foo');

$this->assertCount(2, $ships = $this->build()->get('Ships'));

$this->assertEquals(['Bar'], $ships->first()->resolveChildren()->children()->map->display()->all());
$this->assertEquals(['Foo', 'Bar'], $ships->last()->resolveChildren()->children()->map->display()->all());
}

/** @test */
public function it_can_use_extend_to_defer_until_after_statamic_core_nav_items_are_built()
{
Expand Down Expand Up @@ -378,6 +434,33 @@ public function it_can_use_extend_to_remove_a_default_statamic_nav_item()
$this->assertNotContains('Collections', $this->build()->get('Content')->map->display());
}

/** @test */
public function it_can_use_extend_to_remove_a_default_statamic_child_nav_item()
{
Facades\Collection::make('articles')->save();
Facades\Collection::make('pages')->save();

$this->actingAs(tap(User::make()->makeSuper())->save());

$nav = Nav::build();

$collectionsChildren = function () {
return $this->build()
->get('Content')
->first(fn ($item) => $item->display() === 'Collections')
->resolveChildren()
->children();
};

$this->assertEquals(['Articles', 'Pages'], $collectionsChildren()->map->display()->all());

Nav::extend(function ($nav) {
$nav->remove('Content', 'Collections', 'Articles');
});

$this->assertEquals(['Pages'], $collectionsChildren()->map->display()->all());
}

/** @test */
public function it_checks_if_active()
{
Expand Down

0 comments on commit 366ff26

Please sign in to comment.