Skip to content

Commit

Permalink
add feature to use menu as filament dashboard menu
Browse files Browse the repository at this point in the history
  • Loading branch information
3x1io committed May 15, 2024
1 parent c72bd0b commit 2ccf0f3
Show file tree
Hide file tree
Showing 14 changed files with 509 additions and 38 deletions.
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,37 @@ php artisan filament-menus:install
finally register the plugin on `/app/Providers/Filament/AdminPanelProvider.php`

```php
->plugin(\TomatoPHP\FilamentMenus\FilamentMenusPlugin::make())
->plugins(
\Filament\SpatieLaravelTranslatablePlugin::make()->defaultLocales(['en', 'ar'])
\TomatoPHP\FilamentMenus\FilamentMenusPlugin::make()
)
```

## Usage
## Use as Filament Navigation

you can use this package as a navigation on Filament Admin Panel

```php
use Filament\Navigation\NavigationBuilder;
use Filament\Navigation\NavigationGroup;
use TomatoPHP\FilamentMenus\FilamentMenuLoader;

$panel->navigation(function (NavigationBuilder $builder){
return $builder
// Use Inside Group
->groups([
NavigationGroup::make()
->label('Dashboard')
->items(FilamentMenuLoader::make('dashboard')),
])
// Use Directly
->items(FilamentMenuLoader::make('dashboard'));
})
```

where `dashboard` is a key of menu.

## Use as a Livewire Component

go to route `admin/menus` and create a new menu and you will get the code of livewire component

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"tomatophp/console-helpers": "^1.1",
"tomatophp/filament-icons": "^1.0",
"filament/filament": "^3.0.0",
"filament/notifications": "^3.0.0"
"filament/notifications": "^3.0.0",
"filament/spatie-laravel-translatable-plugin": "^3.0.0"
}
}
11 changes: 10 additions & 1 deletion config/filament-menus.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<?php

return [
//You config go here...
"locals" => [
"ar" => [
"ar" => "العربية",
"en" => "الإنجليزية"
],
"en" => [
"ar" => "Arabic",
"en" => "English"
]
]
];
55 changes: 55 additions & 0 deletions database/migrations/2024_05_13_192724_create_menu_items_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('menu_items', function (Blueprint $table) {
$table->id();
$table->foreignId('menu_id')->constrained()->onDelete('cascade');

//Item Title
$table->json('title');
$table->string('icon')->default('primary')->nullable();


//Badge Options
$table->string('badge_color')->nullable();
$table->boolean('has_badge')->default(1)->nullable();
$table->boolean('has_badge_query')->default(1)->nullable();
$table->string('badge_table')->nullable();
$table->string('badge_condation')->nullable();
$table->json('badge')->nullable();

//URL Options
$table->boolean('is_route')->default(1)->nullable();
$table->string('route')->nullable();
$table->string('url')->nullable();
$table->boolean('new_tab')->nullable();

//Permissions
$table->json('permissions')->nullable();
$table->integer('order')->default(0)->nullable();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('menu_items');
}
};
9 changes: 9 additions & 0 deletions resources/lang/en/messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,19 @@
"item" => [
"item" => "New Item",
"title" => "Title",
"group" => "Group",
"language" => "Language",
"url" => "URL",
"route" => "Route",
"icon" => "Icon",
"target" => "Open in new tab",
"badge_color" => "Badge Color",
"badge" => "Badge",
"is_route" => "Is Route",
"permissions" => "Permissions",
"has_badge" => "Has Badge",
"badge_model" => "Badge Model",
"badge_condation" => "Badge Condition",
],
],
"filters" => [
Expand Down
18 changes: 18 additions & 0 deletions resources/views/menu-item-column.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@php
$record = \TomatoPHP\FilamentMenus\Models\MenuItem::find($getState());
@endphp
<div class="flex justify-start gap-2">
@if(!empty($record->icon))
<x-icon :name="$record->icon" class="w-6 h-6"/>
@endif
<div>
{{ $record->title[app()->getLocale()] }}
</div>
@if($record->has_badge)
<div>
<x-filament::badge :hidden="$record->has_badge">
{{ $record->badge[app()->getLocale()] }}
</x-filament::badge>
</div>
@endif
</div>
6 changes: 6 additions & 0 deletions src/Models/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,10 @@ class Menu extends Model
"items" => "array"
];


public function menuItems()
{
return $this->hasMany(MenuItem::class, 'menu_id', 'id');
}

}
62 changes: 62 additions & 0 deletions src/Models/MenuItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace TomatoPHP\FilamentMenus\Models;

use Filament\Resources\Concerns\Translatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class MenuItem extends Model
{
use HasFactory;
use Translatable;

public array $translatable = [
'title',
'badge'
];

protected $casts = [
'title' => 'array',
'badge' => 'array',
'permissions' => 'array'
];

/**
* The table name
*
* @var string
*/
protected $table = "menu_items";

/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
"menu_id",
"title",
"group",
"icon",
"badge_color",
"has_badge",
"has_badge_query",
"badge_table",
"badge_condation",
"badge",
"is_route",
"route",
"url",
"new_tab",
"permissions",
"order",
];


public function menu()
{
return $this->belongsTo(Menu::class, 'menu_id', 'id');
}

}
63 changes: 30 additions & 33 deletions src/Resources/MenuResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

namespace TomatoPHP\FilamentMenus\Resources;

use App\Forms\Components\Translation;
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
use Filament\Forms;
use Filament\Resources\Resource;
use Filament\Tables\Actions\ActionGroup;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\ViewAction;
use Spatie\Permission\Models\Permission;
use TomatoPHP\FilamentIcons\Components\IconPicker;
use TomatoPHP\FilamentMenus\Models\Menu;
use Filament\Tables;
Expand All @@ -16,6 +19,7 @@
use Illuminate\Support\Facades\Route;
use TomatoPHP\FilamentMenus\Resources\MenuResource\Pages;
use Illuminate\Contracts\Database\Eloquent\Builder;
use TomatoPHP\FilamentMenus\Resources\MenuResource\Relations\MenuItems;

class MenuResource extends Resource
{
Expand All @@ -34,21 +38,33 @@ public static function getNavigationLabel(): string
return trans('filament-menus::messages.title');
}

public static function form(Forms\Form $form): Forms\Form
public static function getPluralLabel(): ?string
{
return trans('filament-menus::messages.title');
}

public static function getLabel(): ?string
{
return trans('filament-menus::messages.title');
}

public static function getModelLabel(): string
{
$routeList = [];
$routeCollection = Route::getRoutes();
foreach ($routeCollection as $key => $route) {
if (isset($route->action['as'])) {
$routeList[$route->action['as']] = $route->uri;
} else {
array_push($routeList, $route->uri);
}
}
return trans('filament-menus::messages.title');
}

public static function getRelations(): array
{
return [
MenuItems::make()
];
}

public static function form(Forms\Form $form): Forms\Form
{
return $form
->schema([
Grid::make(["default" => 1])->schema([
Grid::make(["default" => 3])->schema([
Forms\Components\TextInput::make('title')
->label(trans('filament-menus::messages.cols.title'))
->required()
Expand All @@ -62,29 +78,8 @@ public static function form(Forms\Form $form): Forms\Form
->required()
->default('header')
->maxLength(255),
Forms\Components\Repeater::make('items')
->label(trans('filament-menus::messages.cols.item.item'))
->schema([
Forms\Components\TextInput::make('title')
->label(trans('filament-menus::messages.cols.item.title'))
->required()
->maxLength(255),
Forms\Components\TextInput::make('url')
->label(trans('filament-menus::messages.cols.item.url'))
->required()
->maxLength(255),
Forms\Components\Select::make('route')
->label(trans('filament-menus::messages.cols.item.route'))
->searchable()
->options($routeList),
IconPicker::make('icon')
->label(trans('filament-menus::messages.cols.item.icon'))
->required(),
Forms\Components\Toggle::make('blank')
->label(trans('filament-menus::messages.cols.item.target'))
->required(),
]),
Forms\Components\Toggle::make('activated')
->default(true)
->label(trans('filament-menus::messages.cols.activated'))
->required(),
])
Expand Down Expand Up @@ -131,6 +126,8 @@ public static function getPages(): array
{
return [
'index' => Pages\ManageMenus::route('/'),
'create' => Pages\CreateMenus::route('/create'),
'edit' => Pages\EditMenus::route('/{record}'),
];
}
}
26 changes: 26 additions & 0 deletions src/Resources/MenuResource/Pages/CreateMenus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace TomatoPHP\FilamentMenus\Resources\MenuResource\Pages;

use Filament\Actions\CreateAction;
use Filament\Resources\Pages\CreateRecord;
use TomatoPHP\FilamentMenus\Resources\MenuResource;
use Filament\Resources\Pages\ManageRecords;

class CreateMenus extends CreateRecord
{
protected static string $resource = MenuResource::class;

#[Reactive]
public ?string $local = "en";
public function setLocal($local){
$this->local = $local;
$this->activeLocale = $local;
}


public function getTitle(): string
{
return trans('filament-menus::messages.title');
}
}
26 changes: 26 additions & 0 deletions src/Resources/MenuResource/Pages/EditMenus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace TomatoPHP\FilamentMenus\Resources\MenuResource\Pages;

use Filament\Actions\CreateAction;
use Filament\Resources\Pages\EditRecord;
use TomatoPHP\FilamentMenus\Resources\MenuResource;
use Filament\Resources\Pages\ManageRecords;

class EditMenus extends EditRecord
{
protected static string $resource = MenuResource::class;

#[Reactive]
public ?string $local = "en";
public function setLocal($local){
$this->local = $local;
$this->activeLocale = $local;
}


public function getTitle(): string
{
return trans('filament-menus::messages.title');
}
}
Loading

0 comments on commit 2ccf0f3

Please sign in to comment.