Add Menu Tree functionality and integrate Filament Tree plugin: Introduced a new MenuTree page for managing page structures, added PagesMenuWidget for displaying a tree layout of pages, and updated localization files for menu-related actions. Enhanced Page model with tree management capabilities and included necessary CSS and JS files for the Filament Tree plugin.
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Filament\Admin\Resources\Pages;
|
||||
use App\Filament\Admin\Resources\Pages\Pages\CreatePage;
|
||||
use App\Filament\Admin\Resources\Pages\Pages\EditPage;
|
||||
use App\Filament\Admin\Resources\Pages\Pages\ListPages;
|
||||
use App\Filament\Admin\Resources\Pages\Pages\MenuTree;
|
||||
use App\Filament\Admin\Resources\Pages\Schemas\PageForm;
|
||||
use App\Filament\Admin\Resources\Pages\Tables\PagesTable;
|
||||
use App\Models\Page;
|
||||
@@ -60,6 +61,7 @@ class PageResource extends Resource
|
||||
'index' => ListPages::route('/'),
|
||||
'create' => CreatePage::route('/create'),
|
||||
'edit' => EditPage::route('/{record}/edit'),
|
||||
'menu' => MenuTree::route('/menu'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Filament\Admin\Resources\Pages\Pages;
|
||||
|
||||
use App\Filament\Admin\Resources\Pages\PageResource;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
@@ -18,6 +19,11 @@ class ListPages extends ListRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Action::make('menu')
|
||||
->label(__('pages.menu_tree_title'))
|
||||
->icon('heroicon-o-bars-3')
|
||||
->url(PageResource::getUrl('menu'))
|
||||
->color('gray'),
|
||||
CreateAction::make()
|
||||
->label(__('pages.create')),
|
||||
];
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\Pages\Pages;
|
||||
|
||||
use App\Filament\Admin\Resources\Pages\PageResource;
|
||||
use App\Filament\Admin\Widgets\PagesMenuWidget;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Resources\Pages\Page;
|
||||
|
||||
class MenuTree extends Page
|
||||
{
|
||||
protected static string $resource = PageResource::class;
|
||||
|
||||
protected string $view = 'filament.admin.pages.menu-tree';
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return __('pages.menu_tree_title');
|
||||
}
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Action::make('refresh')
|
||||
->label(__('pages.menu_refresh'))
|
||||
->icon('heroicon-o-arrow-path')
|
||||
->color('gray')
|
||||
->action(function () {
|
||||
$this->dispatch('$refresh');
|
||||
}),
|
||||
Action::make('back_to_pages')
|
||||
->label(__('pages.menu_back_to_pages'))
|
||||
->icon('heroicon-o-arrow-left')
|
||||
->url(PageResource::getUrl('index'))
|
||||
->color('gray'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getHeaderWidgets(): array
|
||||
{
|
||||
return [
|
||||
PagesMenuWidget::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Widgets;
|
||||
|
||||
use App\Filament\Admin\Resources\Pages\PageResource;
|
||||
use App\Models\Page;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use SolutionForest\FilamentTree\Actions\EditAction;
|
||||
use SolutionForest\FilamentTree\Actions\ViewAction;
|
||||
use SolutionForest\FilamentTree\Widgets\Tree as BaseWidget;
|
||||
|
||||
class PagesMenuWidget extends BaseWidget
|
||||
{
|
||||
protected static string $model = Page::class;
|
||||
|
||||
protected static int $maxDepth = 4;
|
||||
|
||||
protected ?string $treeTitle = null;
|
||||
|
||||
protected bool $enableTreeTitle = true;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
parent::mount();
|
||||
$this->treeTitle = __('pages.menu_tree_title');
|
||||
}
|
||||
|
||||
protected function getTreeQuery(): Builder
|
||||
{
|
||||
return Page::query()
|
||||
->where('status', 'published')
|
||||
->where('show_in_menu', true)
|
||||
->orderBy('sort_order');
|
||||
}
|
||||
|
||||
public function getTreeRecordTitle(?\Illuminate\Database\Eloquent\Model $record = null): string
|
||||
{
|
||||
if (!$record) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$title = $record->title;
|
||||
|
||||
// Add child count indicator
|
||||
$childCount = $record->children()
|
||||
->where('status', 'published')
|
||||
->where('show_in_menu', true)
|
||||
->count();
|
||||
|
||||
if ($childCount > 0) {
|
||||
$title .= " ({$childCount})";
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
public function getTreeRecordIcon(?\Illuminate\Database\Eloquent\Model $record = null): ?string
|
||||
{
|
||||
if (!$record) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Root pages get folder icon (parent_id is null)
|
||||
if ($record->parent_id === null) {
|
||||
return 'heroicon-o-folder';
|
||||
}
|
||||
|
||||
// Homepage gets special icon
|
||||
if ($record->is_homepage) {
|
||||
return 'heroicon-o-home';
|
||||
}
|
||||
|
||||
// Child pages get document icon
|
||||
return 'heroicon-o-document-text';
|
||||
}
|
||||
|
||||
protected function hasDeleteAction(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function hasEditAction(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function hasViewAction(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function configureEditAction(EditAction $action): EditAction
|
||||
{
|
||||
return $action
|
||||
->icon('heroicon-o-pencil')
|
||||
->label(__('pages.edit'))
|
||||
->url(fn (Page $record): string => PageResource::getUrl('edit', ['record' => $record]))
|
||||
->openUrlInNewTab(false);
|
||||
}
|
||||
|
||||
protected function configureViewAction(ViewAction $action): ViewAction
|
||||
{
|
||||
return $action
|
||||
->icon('heroicon-o-eye')
|
||||
->label(__('pages.view'))
|
||||
->url(fn (Page $record): string => $record->url)
|
||||
->openUrlInNewTab(true);
|
||||
}
|
||||
|
||||
public function getNodeCollapsedState(?\Illuminate\Database\Eloquent\Model $record = null): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+25
-1
@@ -7,10 +7,11 @@ use App\Traits\HasTranslations;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use SolutionForest\FilamentTree\Concern\ModelTree;
|
||||
|
||||
class Page extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes, HasTranslations;
|
||||
use HasFactory, SoftDeletes, HasTranslations, ModelTree;
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
@@ -172,4 +173,27 @@ class Page extends Model
|
||||
];
|
||||
})->filter(fn($section) => $section['template'] !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* ModelTree - Custom column names
|
||||
*/
|
||||
public function determineOrderColumnName(): string
|
||||
{
|
||||
return 'sort_order';
|
||||
}
|
||||
|
||||
public function determineParentColumnName(): string
|
||||
{
|
||||
return 'parent_id';
|
||||
}
|
||||
|
||||
public function determineTitleColumnName(): string
|
||||
{
|
||||
return 'title';
|
||||
}
|
||||
|
||||
public static function defaultParentKey()
|
||||
{
|
||||
return null; // Mevcut migration nullable olduğu için null kullanıyoruz
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user