### Install and Configure Filament NestedSet Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md Commands to install the package via Composer and publish necessary assets including configuration, views, and translations. These commands prepare the environment for managing nested set data structures. ```bash composer require wsmallnews/filament-nestedset:^2.0 php artisan vendor:publish --tag="sn-filament-nestedset-config" php artisan vendor:publish --tag="sn-filament-nestedset-views" php artisan vendor:publish --tag="sn-filament-nestedset-translations" ``` -------------------------------- ### Create Custom Nestedset Page in PHP Source: https://context7.com/wsmallnews/filament-nestedset/llms.txt Demonstrates how to extend the `NestedsetPage` class to create a custom page for managing a nested set structure. It covers essential configurations like model, title attribute, and optional settings for depth, labels, and UI elements. This example shows how to define schemas for general, create, and edit forms, as well as infolist details and tabbed filtering. ```php label('Category Name') ->required() ->maxLength(255), TextInput::make('slug') ->label('Slug') ->required() ->unique(ignoreRecord: true), Textarea::make('description') ->label('Description') ->rows(3), ]; } /** * Define create-specific form schema. * Overrides schema() for create action only. */ protected function createSchema(array $arguments): array { return [ TextInput::make('name') ->label('Category Name') ->required() ->live(onBlur: true) ->afterStateUpdated(fn ($set, $state) => $set('slug', str($state)->slug())), TextInput::make('slug') ->label('Slug') ->required(), ]; } /** * Define edit-specific form schema. * Overrides schema() for edit action only. */ protected function editSchema(array $arguments): array { return [ TextInput::make('name') ->label('Category Name') ->required(), TextInput::make('slug') ->label('Slug') ->required() ->disabled(), Textarea::make('description') ->label('Description'), ]; } /** * Define additional attributes displayed in each tree row. * Returns Filament infolist components. */ protected function infolistSchema(): array { return [ TextEntry::make('slug') ->label('Slug') ->badge(), TextEntry::make('created_at') ->label('Created') ->dateTime('M d, Y'), ]; } /** * Customize node label display (supports HtmlString). */ public function getRecordLabel(Model $record): HtmlString|string { $icon = $record->isRoot() ? '📁' : '📄'; return "{$icon} {$record->name}"; } /** * Define tabs for filtering tree data. * Each tab creates a separate scoped tree view. */ public function getTabs(): array { return [ 'products' => Tab::make()->label('Product Categories'), 'blog' => Tab::make()->label('Blog Categories'), 'pages' => Tab::make()->label('Page Categories'), ]; } /** * Add additional scope parameters for kalnoy/nestedset scoping. */ public function nestedScoped(): array { return ['status' => 'active']; } /** * Add custom Eloquent query conditions. */ // public function getEloquentQuery(): Builder // { // return parent::getEloquentQuery()->where('is_published', true); // } } ``` -------------------------------- ### Install Filament NestedSet via Composer Source: https://context7.com/wsmallnews/filament-nestedset/llms.txt Use Composer to add the Filament NestedSet package to your Laravel project. This command fetches the latest compatible version for Filament v4 or v5. ```bash composer require wsmallnews/filament-nestedset:^2.0 ``` -------------------------------- ### Run Database Migrations Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md This command executes all pending database migrations, including those that add the nested set fields to your tables. ```bash php artisan migrate ``` -------------------------------- ### Configure Custom Theme Assets Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md Instructions for disabling automatic asset loading and manually importing the package CSS into a Filament custom theme. ```php return [ ... 'autoload_assets' => false, ]; ``` ```css @import '../../../../vendor/wsmallnews/filament-nestedset/resources/css/index.css'; ``` -------------------------------- ### Prepare Eloquent Model with NodeTrait Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md This snippet shows how to prepare an Eloquent model for use with the nestedset package by using the NodeTrait. Ensure your model extends Eloquent's Model and uses the NodeTrait. ```php false, 'allow_delete_root' => false, 'create_action_modal_show_parent_select' => true, 'show_create_child_node_action_in_row' => true, 'autoload_assets' => true, ]; ``` -------------------------------- ### Configure NestedSet Plugin Settings Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md The configuration file allows developers to define constraints such as preventing the deletion of parent nodes or root nodes, toggling the parent select field in modals, and managing asset loading. ```php return [ /** * Restrict deletion of nodes with children */ 'allow_delete_parent' => false, /* * Restrict deletion of root nodes, even if 'allow_delete_parent' is true, root nodes can be deleted. */ 'allow_delete_root' => false, /** * create action show parent select field */ 'create_action_modal_show_parent_select' => true, /** * Display the "Create Child Node" action in each row (if 'create_action_modal_show_parent_select' is false, This field should be set to true) */ 'show_create_child_node_action_in_row' => true, /** * By default, the CSS file will be automatically loaded globally. If you use a filament custom theme, you can disable the automatic loading of the CSS file */ 'autoload_assets' => true, ]; ``` -------------------------------- ### Customize Nestedset Component Logic Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md Demonstrates how to extend the Nestedset class to customize record labels, active states, click event handling, and URL generation for nodes. ```php namespace App\Livewire\Components; use App\Models\Category; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\HtmlString; use Livewire\Attributes\On; use Wsmallnews\FilamentNestedset\Livewire\Components\Nestedset; use function Filament\Support\generate_href_html; class Categories extends Nestedset { public function getRecordLabel(Model $record): HtmlString | string { return $record->name_label; } public function getHasActive(Model $record): bool { return $record->has_active; } #[On('sn-filament-nestedset-leaf-click')] public function clickCategory($recordId) { $this->categoryId = $recordId; } public function getRecordUrl(Model $record): string | HtmlString | null { return generate_href_html(route('categories.show', $record->id), false); } public function getNestedset() { return Category::normal()->defaultOrder() ->get()->toTree(); } } ``` -------------------------------- ### Configure Multi-Tenancy for Navigation Model Source: https://context7.com/wsmallnews/filament-nestedset/llms.txt This PHP code configures the `Navigation` model to support multi-tenancy by defining scope attributes. It ensures that tree data is automatically scoped to the current tenant via the `team_id`. ```php belongsTo(Team::class); } } ``` -------------------------------- ### Configure Tabs Support (PHP) Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md Implement tabbed navigation for your nestedset data by defining a $tabFieldName and the getTabs method. This integrates with the 'kalnoy/nestedset' scoping feature. ```php Tab::make()->label('Website Navigation'), 'shop' => Tab::make()->label('Shop Navigation') ]; } ... } ``` -------------------------------- ### Customize Eloquent Query for Nested Sets Source: https://context7.com/wsmallnews/filament-nestedset/llms.txt Demonstrates how to override the Eloquent query to filter nodes by visibility and implement dynamic level restrictions based on user roles. This approach ensures that data access is restricted according to business logic. ```php public function getEloquentQuery($query) { return $query->where('is_visible', true); } /** * Dynamic level calculation. */ public function getLevel(): ?int { // Allow deeper nesting for admins return auth()->user()?->is_admin ? null : 3; } ``` -------------------------------- ### Define Separate Schemas for Create and Edit in Nestedset Page Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md This demonstrates how to define distinct form schemas for creating new nodes and editing existing ones. Implement `createSchema` and `editSchema` methods separately. ```php required(), TextInput::make('url')->url(), ]; } } ``` -------------------------------- ### Prepare Eloquent Model for Nested Sets Source: https://context7.com/wsmallnews/filament-nestedset/llms.txt Integrate the NodeTrait into your Eloquent model to enable hierarchical functionality. The getScopeAttributes method allows for multi-tenancy or scoped tree operations. ```php children->count(); $badge = $childCount > 0 ? " {$childCount}" : ''; return new HtmlString($record->name . $badge); } /** * Determine if a node should show active state. */ public function getHasActive(Model $record): bool { return $record->id === $this->selectedCategoryId; } /** * Generate URL for node links. * Return null to use click events instead. */ public function getRecordUrl(Model $record): string|HtmlString|null { return generate_href_html( route('categories.show', $record->slug), shouldOpenInNewTab: false ); } /** * Handle leaf node click event. * Dispatched when clicking nodes without children. */ #[On('sn-filament-nestedset-leaf-click')] public function handleLeafClick(int $recordId): void { $this->selectedCategoryId = $recordId; $this->dispatch('category-selected', categoryId: $recordId); } /** * Handle parent node click event. * Dispatched when clicking nodes with children. */ #[On('sn-filament-nestedset-node-click')] public function handleNodeClick(int $recordId): void { // Toggle expansion or navigate $this->selectedCategoryId = $recordId; } /** * Provide the nested set data. * Override for custom queries or filtering. */ public function getNestedset(): Collection { return Category::query() ->where('is_visible', true) ->defaultOrder() ->withDepth() ->get() ->toTree(); } /** * Add scoping parameters for filtered trees. */ public function nestedScoped(): array { return ['type' => 'navigation']; } /** * Add custom query conditions. */ public function getEloquentQuery($query) { return $query->where('status', 'published'); } } ``` -------------------------------- ### Other Customizable Properties for Nestedset Page Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md This snippet showcases various other properties that can be customized for a Filament nestedset page, including model binding, labels, titles, navigation settings, and slugs. ```php id(); $table->string('name'); $table->string('slug')->unique(); $table->text('description')->nullable(); $table->nestedSet(); $table->foreignId('team_id')->nullable()->constrained(); $table->string('type')->default('default'); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('categories'); } }; ``` -------------------------------- ### Define Unified Schema for Create/Edit in Nestedset Page Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md This method defines the form schema that will be used for both creating new nodes and editing existing ones in the nestedset page. It accepts an array of arguments. ```php 5]; } ... } ``` -------------------------------- ### Implement KalnoyNestedsetSelectTree Field Source: https://context7.com/wsmallnews/filament-nestedset/llms.txt Configures a hierarchical select field for Filament forms using the KalnoyNestedsetSelectTree component. It supports depth limiting, searchability, and custom query scoping for nested category models. ```php protected function getFormSchema(): array { return [ TextInput::make('name') ->required(), KalnoyNestedsetSelectTree::make('category_id') ->label('Category') ->level(3) ->searchable() ->query( fn () => Category::scoped(['type' => 'products']), titleAttribute: 'name', parentAttribute: NestedSet::PARENT_ID ) ->enableBranchNode() ->withCount() ->placeholder('Select a category') ->emptyLabel('No categories available') ->treeKey('ProductCategory') ->required(), ]; } ``` -------------------------------- ### Custom Record Label for Nestedset Page Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md This method allows for custom formatting of the record label displayed in the nestedset tree. It supports returning an HtmlString for richer display options. ```php {static::getRecordTitleAttribute()} ?? ' '; } ... } ``` -------------------------------- ### Disable Scoping to Tenant (PHP) Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md If your Filament panel supports multi-tenancy but a specific page does not require tenant distinction, set the static property $isScopedToTenant to false. ```php nestedSet()` method is key for this. ```php nestedSet(); ... }); } }; ``` -------------------------------- ### Add Custom Eloquent Query Conditions (PHP) Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md Modify the default Eloquent query used for fetching nested set data by implementing the getEloquentQuery method. This allows you to add custom where clauses or other query builder methods. ```php where('status', 'normal'); } ... } ``` -------------------------------- ### Disable Auto-Loading of Nestedset Assets Source: https://context7.com/wsmallnews/filament-nestedset/llms.txt To integrate with a custom Filament theme, disable the automatic loading of the package's assets by setting 'autoload_assets' to false in the configuration file. This prevents CSS conflicts and allows for manual import. ```php // config/sn-filament-nestedset.php return [ // Disable automatic CSS loading 'autoload_assets' => false, ]; ``` -------------------------------- ### Model Scope Attributes for Tabs (PHP) Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md When using tab support, ensure your model's getScopeAttributes method includes the field specified by $tabFieldName (e.g., 'type') to correctly scope the nested set data. ```php nestedSet()` method. ```php nestedSet(); }); } }; ``` -------------------------------- ### Define Empty Label Text for Nestedset Page Source: https://github.com/wsmallnews/filament-nestedset/blob/v2/README.md This property allows you to customize the text displayed when the nestedset tree is empty. It provides a user-friendly message for the initial state. ```php