Skip to content

Commit 3a4c62b

Browse files
committed
Refactor to solution-forest/filament-tree.
1 parent 35ca429 commit 3a4c62b

File tree

6 files changed

+93
-113
lines changed

6 files changed

+93
-113
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ php artisan vendor:publish --tag="filament-flexible-content-block-pages-migratio
4747
php artisan migrate
4848
```
4949

50+
Configure the Filament tailwind styling by adding these view paths to `tailwind.config.js`:
51+
52+
```php
53+
content: [
54+
...
55+
'./vendor/solution-forest/filament-tree/resources/**/*.blade.php',
56+
'./vendor/statikbe/laravel-filament-flexible-content-block-pages/**/*.blade.php',
57+
]
58+
```
59+
5060
You can now seed the home page and default settings by running:
5161

5262
```bash

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
],
1818
"require": {
1919
"php": "^8.2",
20-
"15web/filament-tree": "^1.0",
2120
"artesaos/seotools": "^1.3",
2221
"filament/spatie-laravel-tags-plugin": "^3.2",
2322
"guava/filament-icon-picker": "^2.0",
2423
"illuminate/contracts": "^10.0||^11.0||^12.0",
25-
"kalnoy/nestedset": "^6.0",
2624
"mcamara/laravel-localization": "^2.3",
25+
"solution-forest/filament-tree": "^2.1",
2726
"spatie/laravel-missing-page-redirector": "^2.11",
2827
"spatie/laravel-package-tools": "^1.16",
2928
"statikbe/laravel-filament-flexible-content-blocks": "dev-main"

database/migrations/create_filament_flexible_content_block_menu_items_table.php.stub

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use Illuminate\Database\Migrations\Migration;
44
use Illuminate\Database\Schema\Blueprint;
55
use Illuminate\Support\Facades\Schema;
6-
use Kalnoy\Nestedset\NestedSet;
76
use Statikbe\FilamentFlexibleContentBlockPages\Facades\FilamentFlexibleContentBlockPages;
87

98
return new class extends Migration
@@ -32,8 +31,7 @@ return new class extends Migration
3231
$table->boolean('is_visible')->default(true);
3332
$table->boolean('use_model_title')->default(false);
3433

35-
// Nested set structure
36-
NestedSet::columns($table);
34+
$table->treeColumns();
3735

3836
$table->timestamps();
3937

src/Models/MenuItem.php

Lines changed: 17 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,21 @@
22

33
namespace Statikbe\FilamentFlexibleContentBlockPages\Models;
44

5-
use Illuminate\Database\Eloquent\Casts\Attribute;
65
use Illuminate\Database\Eloquent\Factories\HasFactory;
76
use Illuminate\Database\Eloquent\Model;
87
use Illuminate\Database\Eloquent\Relations\BelongsTo;
98
use Illuminate\Database\Eloquent\Relations\MorphTo;
10-
use Kalnoy\Nestedset\NodeTrait;
9+
use SolutionForest\FilamentTree\Concern\ModelTree;
1110
use Spatie\Translatable\HasTranslations;
1211
use Statikbe\FilamentFlexibleContentBlockPages\Facades\FilamentFlexibleContentBlockPages;
1312
use Statikbe\FilamentFlexibleContentBlockPages\Models\Contracts\HasMenuLabel;
1413
use Statikbe\FilamentFlexibleContentBlocks\Models\Contracts\Linkable;
15-
use Studio15\FilamentTree\Concerns\InteractsWithTree;
1614

1715
class MenuItem extends Model
1816
{
1917
use HasFactory;
2018
use HasTranslations;
21-
use InteractsWithTree;
22-
use NodeTrait;
19+
use ModelTree;
2320

2421
protected $fillable = [
2522
'menu_id',
@@ -33,14 +30,15 @@ class MenuItem extends Model
3330
'icon',
3431
'is_visible',
3532
'use_model_title',
36-
'_lft',
37-
'_rgt',
33+
'order',
3834
'parent_id',
3935
];
4036

4137
protected $casts = [
4238
'is_visible' => 'boolean',
4339
'use_model_title' => 'boolean',
40+
'parent_id' => 'int',
41+
'order' => 'int',
4442
];
4543

4644
public $translatable = ['label'];
@@ -60,6 +58,16 @@ public function linkable(): MorphTo
6058
return $this->morphTo('linkable', 'linkable_type', 'linkable_id');
6159
}
6260

61+
public function parent()
62+
{
63+
return $this->belongsTo(static::class, $this->determineParentColumnName());
64+
}
65+
66+
public function getMorphClass()
67+
{
68+
return 'filament-flexible-content-block-pages::menu-item';
69+
}
70+
6371
public function getUrl(?string $locale = null): ?string
6472
{
6573
// If it has a linkable model, get URL from that
@@ -98,49 +106,8 @@ public function isVisible(): bool
98106
return $this->is_visible;
99107
}
100108

101-
public function canHaveChildren(): bool
102-
{
103-
$maxDepth = FilamentFlexibleContentBlockPages::config()->getMenuMaxDepth();
104-
105-
return $this->depth < $maxDepth;
106-
}
107-
108-
public function getMorphClass()
109-
{
110-
return 'filament-flexible-content-block-pages::menu-item';
111-
}
112-
113-
public static function getTreeLabelAttribute(): string
114-
{
115-
return 'tree_label';
116-
}
117-
118-
protected function treeLabel(): Attribute
119-
{
120-
return Attribute::make(
121-
get: fn (string $value) => $this->getDisplayLabel(),
122-
);
123-
}
124-
125-
public function getTreeCaption(): string
126-
{
127-
if ($this->linkable_type && $this->linkable) {
128-
return flexiblePagesTrans('menu_items.tree.linked_to').' '.class_basename($this->linkable_type);
129-
}
130-
131-
if ($this->url) {
132-
return flexiblePagesTrans('menu_items.tree.external_url').': '.$this->url;
133-
}
134-
135-
if ($this->route) {
136-
return flexiblePagesTrans('menu_items.tree.route').': '.$this->route;
137-
}
138-
139-
return flexiblePagesTrans('menu_items.tree.no_link');
140-
}
141-
142-
public function getScopeAttributes(): array
109+
public function getTitleAttribute(): string
143110
{
144-
return ['menu_id'];
111+
return $this->getDisplayLabel();
145112
}
146113
}

src/Resources/MenuResource.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Filament\Forms\Components\Textarea;
88
use Filament\Forms\Components\TextInput;
99
use Filament\Forms\Form;
10+
use Filament\Resources\Concerns\Translatable;
1011
use Filament\Resources\Resource;
1112
use Filament\Tables\Actions\Action;
1213
use Filament\Tables\Actions\DeleteBulkAction;
@@ -22,6 +23,12 @@
2223

2324
class MenuResource extends Resource
2425
{
26+
/*
27+
* For translating menu item labels
28+
* @see ManageMenuItems
29+
*/
30+
use Translatable;
31+
2532
protected static ?string $navigationIcon = 'heroicon-o-bars-3';
2633

2734
protected static ?string $recordRouteKeyName = 'id';

src/Resources/MenuResource/Pages/ManageMenuItems.php

Lines changed: 57 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33
namespace Statikbe\FilamentFlexibleContentBlockPages\Resources\MenuResource\Pages;
44

55
use Filament\Actions\LocaleSwitcher;
6-
use Filament\Infolists\Components\IconEntry;
7-
use Filament\Panel;
8-
use Filament\Resources\Concerns\Translatable;
9-
use Filament\Resources\Pages\PageRegistration;
10-
use Illuminate\Routing\Route;
11-
use Illuminate\Support\Facades\Route as RouteFacade;
12-
use Kalnoy\Nestedset\QueryBuilder;
6+
use Illuminate\Database\Eloquent\Model;
7+
use SolutionForest\FilamentTree\Concern\TreeRecords\Translatable;
8+
use SolutionForest\FilamentTree\Actions\Action;
9+
use SolutionForest\FilamentTree\Actions\DeleteAction;
10+
use SolutionForest\FilamentTree\Actions\EditAction;
11+
use SolutionForest\FilamentTree\Pages\TreePage;
1312
use Statikbe\FilamentFlexibleContentBlockPages\Facades\FilamentFlexibleContentBlockPages;
1413
use Statikbe\FilamentFlexibleContentBlockPages\Filament\Form\Forms\MenuItemForm;
14+
use Statikbe\FilamentFlexibleContentBlockPages\Models\MenuItem;
1515
use Statikbe\FilamentFlexibleContentBlockPages\Resources\MenuResource;
16-
use Studio15\FilamentTree\Components\TreePage;
1716

1817
class ManageMenuItems extends TreePage
1918
{
@@ -23,43 +22,23 @@ class ManageMenuItems extends TreePage
2322

2423
public mixed $record;
2524

25+
protected static int $maxDepth = 3;
26+
2627
public function mount(): void
2728
{
28-
parent::mount();
29-
3029
$menuModelClass = MenuResource::getModel();
3130
$recordId = request()->route('record');
3231
$this->record = app($menuModelClass)->findOrFail($recordId);
3332
}
3433

35-
/**
36-
* Copied from Resource/Page to support routing in resources.
37-
* {@inheritDoc}
38-
*/
39-
public static function route(string $path): PageRegistration
40-
{
41-
return new PageRegistration(
42-
page: static::class,
43-
route: fn (Panel $panel): Route => RouteFacade::get($path, static::class)
44-
->middleware(static::getRouteMiddleware($panel))
45-
->withoutMiddleware(static::getWithoutRouteMiddleware($panel)),
46-
);
47-
}
48-
49-
public static function getModel(): string|QueryBuilder
34+
public function getModel(): string
5035
{
5136
return FilamentFlexibleContentBlockPages::config()->getMenuItemModel()::class;
5237
}
5338

54-
protected function getViewData(): array
39+
public function getTranslatableLocales(): array
5540
{
56-
$query = static::getModel()::scoped(['menu_id' => $this->record->id])
57-
->with('linkable')
58-
->defaultOrder();
59-
60-
return [
61-
'tree' => $query->get()->toTree(),
62-
];
41+
return static::getResource()::getTranslatableLocales();
6342
}
6443

6544
public function getTitle(): string
@@ -75,47 +54,67 @@ public function getBreadcrumb(): string
7554
return flexiblePagesTrans('menu_items.manage.breadcrumb');
7655
}
7756

78-
public static function getCreateForm(): array
79-
{
80-
return MenuItemForm::getSchema();
81-
}
82-
83-
public static function getEditForm(): array
57+
protected function getHeaderActions(): array
8458
{
85-
return MenuItemForm::getSchema();
59+
return [
60+
LocaleSwitcher::make(),
61+
];
8662
}
8763

88-
public static function getInfolistColumns(): array
64+
protected function getTreeActions(): array
8965
{
9066
return [
91-
IconEntry::make('is_visible')
92-
->label('')
93-
->icon(fn (bool $state): string => $state ? 'heroicon-o-eye' : 'heroicon-o-eye-slash')
94-
->color(fn (bool $state): string => $state ? 'gray' : 'warning')
95-
->tooltip(fn (bool $state): ?string => $state ? null : flexiblePagesTrans('menu_items.status.hidden'))
96-
->hidden(fn (bool $state): bool => $state)
97-
->size('sm'),
67+
Action::make('create')
68+
->mountUsing(
69+
fn ($arguments, $form, $model) => $form->fill([
70+
'menu_id' => $this->record->id,
71+
'parent_id' => $arguments['parent_id'] ?? -1,
72+
'is_visible' => true,
73+
'target' => '_self',
74+
])
75+
)
76+
->action(function (array $data): void {
77+
$data['menu_id'] = $this->record->id;
78+
static::getModel()::create($data);
79+
}),
80+
EditAction::make()
81+
->mountUsing(
82+
fn ($arguments, $form, $model) => $form->fill([
83+
...$model->toArray(),
84+
'menu_id' => $this->record->id,
85+
])
86+
),
87+
DeleteAction::make(),
9888
];
9989
}
10090

101-
protected function getHeaderActions(): array
91+
protected function getTreeRecords()
10292
{
103-
return [
104-
LocaleSwitcher::make(),
105-
];
93+
return static::getModel()::where('menu_id', $this->record->id)
94+
->with('linkable')
95+
->orderBy('order')
96+
->get();
10697
}
10798

108-
protected function mutateFormDataBeforeCreate(array $data): array
99+
public function getTreeRecordTitle(?Model $record = null): string
109100
{
110-
$data['menu_id'] = $this->record->id;
101+
/** @var MenuItem $record */
102+
if (! $record) {
103+
return '';
104+
}
111105

112-
return $data;
106+
$locale = $this->getActiveLocale();
107+
return $record->getDisplayLabel($locale);
113108
}
114109

115-
protected function mutateFormDataBeforeSave(array $data): array
110+
public function getTreeRecordIcon(?\Illuminate\Database\Eloquent\Model $record = null): ?string
116111
{
117-
$data['menu_id'] = $this->record->id;
112+
//TODO
113+
return parent::getTreeRecordIcon($record);
114+
}
118115

119-
return $data;
116+
protected function getFormSchema(): array
117+
{
118+
return MenuItemForm::getSchema();
120119
}
121120
}

0 commit comments

Comments
 (0)