Skip to content

Commit

Permalink
Pass new nav builder tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseleite committed Nov 22, 2024
1 parent ad7ff8a commit 6d36835
Showing 1 changed file with 64 additions and 44 deletions.
108 changes: 64 additions & 44 deletions src/CP/Navigation/NavBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Statamic\CP\Navigation;

use Exception;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Statamic\Facades\Blink;
use Statamic\Facades\Preference;
Expand Down Expand Up @@ -251,8 +252,8 @@ protected function applyPreferenceOverrides($preferences = null)
->each(fn ($overrides) => $this->createPendingItemsForSection($overrides))
->each(fn ($overrides) => $this->applyPreferenceOverridesForSection($overrides));

if ($navPreferencesConfig['reorder']) {
$this->setSectionOrder($sections);
if ($reorder = $navPreferencesConfig['reorder']) {
$this->setSectionOrder($reorder);
}

return $this;
Expand Down Expand Up @@ -317,8 +318,8 @@ protected function applyPreferenceOverridesForSection($sectionNav)
->filter()
->each(fn ($item) => $item->isChild(false));

if ($sectionNav['reorder']) {
$this->setSectionItemOrder($section, $sectionNav['items']);
if ($reorder = $sectionNav['reorder']) {
$this->setSectionItemOrder($section, $sectionNav['items'], $reorder);
}
}

Expand Down Expand Up @@ -441,62 +442,76 @@ protected function renameSection($sectionKey)

/**
* Set section order.
*
* @param array $sections
*/
protected function setSectionOrder($sections)
protected function setSectionOrder(array $reorder): void
{
// Get conconfigured core sections...
// Get unconfigured core sections...
$unconfiguredCoreSections = $this->sections;

// Get unconfigured sections...
$unconfiguredRegisteredSections = collect($this->items)->map->section()->filter()->unique();
$unconfiguredRegisteredSections = collect($this->items)
->mapWithKeys(fn ($item) => [NavItem::snakeCase($item->section()) => $item->section()])
->filter()
->unique();

// Merge unconfigured sections onto the end of the list and map their order...
$this->sectionsOrder = collect($sections)
->pluck('display')
->merge($unconfiguredRegisteredSections)
// Get merged unique list of sections...
$order = collect()
->merge($unconfiguredCoreSections)
->unique()
->merge($unconfiguredRegisteredSections)
->unique();

// Reorder to match `$reorder` config...
collect($reorder)
->reverse()
->each(fn ($key) => $order->prepend($order->pull($key), $key));

// Ensure `top_level` is always first...
$order->prepend($order->pull('top_level'), 'top_level');

$this->sectionsOrder = $order
->values()
->mapWithKeys(fn ($section, $index) => [$section => $index + 1])
->all();
}

/**
* Set section item order.
*
* @param string $section
* @param array $items
*/
protected function setSectionItemOrder($section, $items)
protected function setSectionItemOrder(string $section, array $items, array $reorder): void
{
// Get unconfigured item IDs...
$unconfiguredItemIds = collect($this->items)
->filter(fn ($item) => $item->section() === $section)
->map
->id();

// Generate IDs for newly created items...
$itemIds = collect($items)
$createdItemIds = collect($items)
->map(function ($item, $id) use ($section, $items) {
return $items[$id]['action'] === '@create'
? $this->generateNewItemId($section, $items[$id]['display'])
: $id;
})
->values();

// Get unconfigured item IDs...
$unconfiguredItemIds = collect($this->items)
->filter(fn ($item) => $item->section() === $section)
->map
->id();

// Merge unconfigured items into the end of the list...
$itemIds = $itemIds
->values()
$itemIds = collect()
->merge($unconfiguredItemIds)
->merge($createdItemIds)
->unique()
->values();
->flip();

// Reorder to match `$reorder` config...
collect($reorder)
->reverse()
->each(fn ($key) => $itemIds->prepend($itemIds->pull($key), $key));

// Set an explicit order value on each item...
$itemIds
->flip()
->map(fn ($id) => $this->findItem($id, false))
->filter()
->values()
->each(fn ($item, $index) => $item->order($index + 1));

// Inform builder that section items should be ordered...
Expand Down Expand Up @@ -668,29 +683,29 @@ protected function userModifyItem($item, $config, $section)
->reject(fn ($value, $setter) => in_array($setter, ['children', 'reorder']))
->each(fn ($value, $setter) => $item->{$setter}($value));

if ($children = $config->get('children')) {
$this->userModifyItemChildren($item, $children, $section, $config->get('reorder'));
$childrenConfig = $config->get('children');
$reorder = $config->get('reorder');

if ($childrenConfig || $reorder) {
$this->userModifyItemChildren($item, $childrenConfig, $section, $reorder);
}

return $item;
}

/**
* Modify NavItem children.
*
* @param \Statamic\CP\Navigation\NavItem $item
* @param array $childrenOverrides
* @param string $section
* @return \Illuminate\Support\Collection
*/
protected function userModifyItemChildren($item, $childrenOverrides, $section, $reorder)
protected function userModifyItemChildren(NavItem $item, ?array $childrenConfig, string $section, ?array $reorder): void
{
// Get original item children...
$itemChildren = collect($item->original()->resolveChildren()->children())
->each(fn ($item, $index) => $item->order($index + 1000))
->keyBy
->id();

collect($childrenOverrides)
// Apply children preferences from config...
collect($childrenConfig)
->map(fn ($config, $key) => $this->userModifyChild($config, $section, $key, $item))
->each(function ($item, $key) use (&$itemChildren) {
$item
Expand All @@ -701,15 +716,20 @@ protected function userModifyItemChildren($item, $childrenOverrides, $section, $
->values()
->each(fn ($item, $index) => $item->order($index + 1));

$newChildren = $reorder
? $itemChildren->sortBy(fn ($item) => $item->order())->values()
: $itemChildren->values();

$newChildren->each(fn ($item, $index) => $item->order($index + 1));
// Reorder to match `$reorder` config...
if ($reorder) {
collect($reorder)
->reverse()
->each(fn ($key) => $itemChildren->prepend($itemChildren->pull($key), $key));
}

$item->children($newChildren, false);
// Update final `order`...
$itemChildren
->sortBy(fn ($item) => $item->order())->values()
->values()
->each(fn ($item, $index) => $item->order($index + 1));

return $newChildren;
$item->children($itemChildren, false);
}

/**
Expand Down

0 comments on commit 6d36835

Please sign in to comment.