Skip to content

Commit

Permalink
Merge pull request #19 from Log1x/feat/refactor-menu-locations
Browse files Browse the repository at this point in the history
♻ Refactor the menu location implementation
  • Loading branch information
datlechin authored Aug 20, 2024
2 parents 38b10a3 + d144111 commit 396d054
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 80 deletions.
4 changes: 1 addition & 3 deletions database/migrations/create_menus_table.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ return new class extends Migration
Schema::create(config('filament-menu-builder.tables.menu_locations'), function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Menu::class)->constrained()->cascadeOnDelete();
$table->string('location', 50);
$table->string('location')->unique();
$table->timestamps();

$table->unique(['menu_id', 'location']);
});
}

Expand Down
27 changes: 20 additions & 7 deletions resources/lang/en/menu-builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,32 @@
'label' => 'Name',
],
'locations' => [
'label' => 'Locations',
'description' => 'Choose where to display the menu.',
'empty' => 'Unassigned',
'actions' => [
'select_all' => 'Select all',
'deselect_all' => 'Deselect all',
],
],
'is_visible' => [
'label' => 'Visible',
'label' => 'Visibility',
'visible' => 'Visible',
'hidden' => 'Hidden',
],
],
'actions' => [
'add' => [
'label' => 'Add to Menu',
],
'locations' => [
'label' => 'Locations',
'heading' => 'Manage Locations',
'description' => 'Choose which menu appears at each location.',
'submit' => 'Update',
'form' => [
'location' => [
'label' => 'Location',
],
'menu' => [
'label' => 'Assigned Menu',
],
],
],
],
'items' => [
'empty' => [
Expand All @@ -48,6 +58,9 @@
'created' => [
'title' => 'Link created',
],
'locations' => [
'title' => 'Menu locations updated',
],
],
'panel' => [
'empty' => [
Expand Down
25 changes: 19 additions & 6 deletions resources/lang/vi/menu-builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,32 @@
'label' => 'Tên',
],
'locations' => [
'label' => 'Vị trí',
'description' => 'Chọn vị trí hiển thị menu.',
'empty' => 'Chưa gán',
'actions' => [
'select_all' => 'Chọn tất cả',
'deselect_all' => 'Bỏ chọn tất cả',
],
],
'is_visible' => [
'label' => 'Hiển thị',
'visible' => 'Hiển thị',
'hidden' => 'Ẩn',
],
],
'actions' => [
'add' => [
'label' => 'Thêm vào Menu',
],
'locations' => [
'label' => 'Vị trí',
'heading' => 'Quản lý vị trí',
'description' => 'Chọn menu nào xuất hiện ở mỗi vị trí.',
'submit' => 'Cập nhật',
'form' => [
'location' => [
'label' => 'Vị trí',
],
'menu' => [
'label' => 'Menu đã gán',
],
],
],
],
'items' => [
'empty' => [
Expand All @@ -48,6 +58,9 @@
'created' => [
'title' => 'Liên kết đã được tạo',
],
'locations' => [
'title' => 'Cập nhật vị trí menu',
],
],
'panel' => [
'empty' => [
Expand Down
85 changes: 85 additions & 0 deletions src/Concerns/HasLocationAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace Datlechin\FilamentMenuBuilder\Concerns;

use Datlechin\FilamentMenuBuilder\FilamentMenuBuilderPlugin;
use Datlechin\FilamentMenuBuilder\Models\MenuLocation;
use Filament\Actions\Action;
use Filament\Forms\Components;
use Filament\Notifications\Notification;
use Filament\Support\Enums\MaxWidth;
use Illuminate\Support\Collection;

trait HasLocationAction
{
protected ?Collection $menuLocations = null;

public function getLocationAction(): Action
{
return Action::make('locations')
->label(__('filament-menu-builder::menu-builder.actions.locations.label'))
->modalHeading(__('filament-menu-builder::menu-builder.actions.locations.heading'))
->modalDescription(__('filament-menu-builder::menu-builder.actions.locations.description'))
->modalSubmitActionLabel(__('filament-menu-builder::menu-builder.actions.locations.submit'))
->modalWidth(MaxWidth::Large)
->color('gray')
->fillForm(fn () => $this->getRegisteredLocations()->map(fn ($location, $key) => [
'location' => $location,
'menu' => $this->getMenuLocations()->where('location', $key)->first()?->menu_id,
])->all())
->action(function (array $data) {
$locations = collect($data)
->map(fn ($item) => $item['menu'] ?? null)
->all();

$this->getMenuLocations()
->pluck('location')
->diff($this->getRegisteredLocations()->keys())
->each(fn ($location) => $this->getMenuLocations()->where('location', $location)->each->delete());

foreach ($locations as $location => $menu) {
if (! $menu) {
$this->getMenuLocations()->where('location', $location)->each->delete();

continue;
}

MenuLocation::updateOrCreate(
['location' => $location],
['menu_id' => $menu]
);
}

Notification::make()
->title(__('filament-menu-builder::menu-builder.notifications.locations.title'))
->success()
->send();
})
->form(fn () => $this->getRegisteredLocations()->map(
fn ($location, $key) => Components\Grid::make(2)
->statePath($key)
->schema([
Components\TextInput::make('location')
->label(__('filament-menu-builder::menu-builder.actions.locations.form.location.label'))
->hiddenLabel($key !== $this->getRegisteredLocations()->keys()->first())
->disabled(),

Components\Select::make('menu')
->label(__('filament-menu-builder::menu-builder.actions.locations.form.menu.label'))
->searchable()
->hiddenLabel($key !== $this->getRegisteredLocations()->keys()->first())
->options($this->getModel()::all()->pluck('name', 'id')->all()),
])
)->all());
}

protected function getMenuLocations(): Collection
{
return $this->menuLocations ??= MenuLocation::all();
}

protected function getRegisteredLocations(): Collection
{
return collect(FilamentMenuBuilderPlugin::get()->getLocations());
}
}
2 changes: 1 addition & 1 deletion src/Livewire/CreateCustomLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function save(): void
'title' => $this->title,
'url' => $this->url,
'target' => $this->target,
'order' => $this->menu->menuItems()->max('order') + 1,
'order' => $this->menu->menuItems->max('order') + 1,
]);

Notification::make()
Expand Down
2 changes: 1 addition & 1 deletion src/Livewire/MenuItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MenuItems extends Component implements HasActions, HasForms
#[On('menu:created')]
public function menuItems(): Collection
{
return $this->menu->menuItems()->get();
return $this->menu->menuItems;
}

public function reorder(array $order, ?string $parentId = null): void
Expand Down
2 changes: 1 addition & 1 deletion src/Livewire/MenuPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function add(): void
{
$this->validate();

$order = $this->menu->menuItems()->max('order') ?? 0;
$order = $this->menu->menuItems->max('order') ?? 0;

$selectedItems = collect($this->items)
->filter(fn ($item) => in_array($item['title'], $this->data))
Expand Down
7 changes: 7 additions & 0 deletions src/Models/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,11 @@ public function menuItems(): HasMany
->orderBy('order')
->with('children');
}

public static function location(string $location): ?self
{
return MenuLocation::with('menu')
->where('location', $location)
->first()?->menu;
}
}
58 changes: 24 additions & 34 deletions src/Resources/MenuResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,9 @@

use Datlechin\FilamentMenuBuilder\FilamentMenuBuilderPlugin;
use Datlechin\FilamentMenuBuilder\Models\Menu;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components;
use Filament\Forms\Components\Component;
use Filament\Forms\Components\Group;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
Expand All @@ -27,36 +21,32 @@ class MenuResource extends Resource

public static function form(Form $form): Form
{
$locations = FilamentMenuBuilderPlugin::get()->getLocations();

return $form
->columns(1)
->schema([
TextInput::make('name')
->label(__('filament-menu-builder::menu-builder.resource.name.label'))
->required(),
ToggleButtons::make('locations')
->multiple()
->inline()
->reactive()
->visible(fn (string $context) => $context === 'edit' && $locations)
->label(__('filament-menu-builder::menu-builder.resource.locations.label'))
->afterStateHydrated(fn (Menu $menu, Set $set) => $set('locations', $menu->locations->pluck('location')))
->helperText(__('filament-menu-builder::menu-builder.resource.locations.description'))
->hintActions([
Action::make(__('filament-menu-builder::menu-builder.resource.locations.actions.select_all'))
->action(fn (Set $set) => $set('locations', array_keys($locations)))
->visible(fn (Get $get) => count($get('locations')) !== count($locations)),
Components\Grid::make(4)
->schema([
Components\TextInput::make('name')
->label(__('filament-menu-builder::menu-builder.resource.name.label'))
->required()
->columnSpan(3),

Action::make(__('filament-menu-builder::menu-builder.resource.locations.actions.deselect_all'))
->action(fn (Set $set) => $set('locations', []))
->visible(fn (Get $get) => count($get('locations')) === count($locations)),
])
->options($locations),
Toggle::make('is_visible')
->label(__('filament-menu-builder::menu-builder.resource.is_visible.label'))
->default(true),
Group::make()
Components\ToggleButtons::make('is_visible')
->grouped()
->options([
true => __('filament-menu-builder::menu-builder.resource.is_visible.visible'),
false => __('filament-menu-builder::menu-builder.resource.is_visible.hidden'),
])
->colors([
true => 'primary',
false => 'danger',
])
->required()
->label(__('filament-menu-builder::menu-builder.resource.is_visible.label'))
->default(true),
]),

Components\Group::make()
->visible(fn (Component $component) => $component->evaluate(FilamentMenuBuilderPlugin::get()->getMenuFields()) !== [])
->schema(FilamentMenuBuilderPlugin::get()->getMenuFields()),
]);
Expand All @@ -73,7 +63,7 @@ public static function table(Table $table): Table
->label(__('filament-menu-builder::menu-builder.resource.name.label')),
Tables\Columns\TextColumn::make('locations.location')
->default($default = __('filament-menu-builder::menu-builder.resource.locations.empty'))
->color(fn (string $state) => $state !== $default ? 'primary' : 'gray')
->color(fn (string $state) => array_key_exists($state, $locations) ? 'primary' : 'gray')
->formatStateUsing(fn (string $state) => $locations[$state] ?? $state)
->limitList(2)
->badge(),
Expand Down
31 changes: 4 additions & 27 deletions src/Resources/MenuResource/Pages/EditMenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

namespace Datlechin\FilamentMenuBuilder\Resources\MenuResource\Pages;

use Datlechin\FilamentMenuBuilder\Concerns\HasLocationAction;
use Datlechin\FilamentMenuBuilder\FilamentMenuBuilderPlugin;
use Datlechin\FilamentMenuBuilder\Models\Menu;
use Filament\Actions;
use Filament\Forms\Components\Section;
use Filament\Forms\Form;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;

class EditMenu extends EditRecord
{
use HasLocationAction;

protected static string $view = 'filament-menu-builder::edit-record';

public static function getResource(): string
Expand All @@ -34,30 +34,7 @@ protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
$this->getLocationAction(),
];
}

protected function handleRecordUpdate(Model $record, array $data): Model
{
$registeredLocations = FilamentMenuBuilderPlugin::get()->getLocations();

$locations = collect(Arr::pull($data, 'locations') ?: [])
->filter(fn ($location) => array_key_exists($location, $registeredLocations))
->values();

/** @var Menu */
$record = parent::handleRecordUpdate($record, $data);

$record->locations()
->whereNotIn('location', $locations)
->delete();

foreach ($locations as $location) {
$record->locations()->firstOrCreate([
'location' => $location,
]);
}

return $record;
}
}
4 changes: 4 additions & 0 deletions src/Resources/MenuResource/Pages/ListMenus.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

namespace Datlechin\FilamentMenuBuilder\Resources\MenuResource\Pages;

use Datlechin\FilamentMenuBuilder\Concerns\HasLocationAction;
use Datlechin\FilamentMenuBuilder\FilamentMenuBuilderPlugin;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

class ListMenus extends ListRecords
{
use HasLocationAction;

public static function getResource(): string
{
return FilamentMenuBuilderPlugin::get()->getResource();
Expand All @@ -19,6 +22,7 @@ protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
$this->getLocationAction(),
];
}
}

0 comments on commit 396d054

Please sign in to comment.