fix: add void return type to configure() for Symfony 8 compatibility#103
fix: add void return type to configure() for Symfony 8 compatibility#103vanneszias wants to merge 159 commits intosolutionforest:masterfrom
Conversation
…translations [ar]: Add Arabic translations
…n-rounded-direction [ui]: Fix the button rounded in RTL.
[ui] Some opinionated UI improvements
Add Turkish translation for filament-tree.php (lang-tr)
Update: Translation directory complies with i18n
…ent-tree into aymanalareqi-fix-rtl-style # Conflicts: # resources/css/button.css # resources/dist/filament-tree.css # resources/dist/filament-tree.js # resources/views/components/tree/item.blade.php
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
…toolbar_actions Feature/add toolbar actions
The README has been rewritten for clarity and completeness, including improved installation steps, detailed quick start, advanced customization, translation support, and best practices. Examples and explanations for widgets, pages, resource integration, and configuration have been updated and expanded. The documentation now better guides users through setup, customization, and advanced features of the Filament Tree plugin.
Fixes incorrect context reference in tree item blade template where $this->getNodeCollapsedState($record) was called from a blade component context where $this doesn't refer to the Livewire component. Changed to use $tree->getLivewire()->getNodeCollapsedState($record) to properly access the method from the correct Livewire component context. This enables proper node collapse state functionality for tree items, allowing developers to override getNodeCollapsedState() to control initial tree node visibility (e.g., starting with collapsed nodes). Fixes solutionforest#88
…decollapsedstate-didnt-work fix: resolve getNodeCollapsedState() method call in tree item template
…-patch-1 Improve Advanced usage documentation
Bumps [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action) from 6 to 7. - [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases) - [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md) - [Commits](stefanzweifel/git-auto-commit-action@v6...v7) --- updated-dependencies: - dependency-name: stefanzweifel/git-auto-commit-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
…ithub_actions/stefanzweifel/git-auto-commit-action-7 Bump stefanzweifel/git-auto-commit-action from 6 to 7
- Replace askForLivewireComponentLocation() with askForLivewireComponentNamespace() - Resolves BadMethodCallException when running make:filament-tree-widget command - Method was attempting to call non-existent askForLivewireComponentLocation from CanAskForLivewireComponentLocation trait Fixes solutionforest#93
Replaces the shorthand each->delete() with an explicit closure to ensure each child model is properly deleted. This improves compatibility and clarity in the child deletion process.
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
…ithub_actions/actions/checkout-6 Bump actions/checkout from 5 to 6
Update notification title on save action
Add Filament v5 compatibility note to README (maps v5 -> 4.x.x) and update composer.json to require filament/filament ^5.0. Also upgrade Pest and related Pest plugins to ^4.0 in require-dev to match the new major version of the test tooling.
Symfony 8 adds a `void` return type declaration to `Command::configure()`. Without matching return types in subclasses, PHP throws a fatal error on class load, breaking package discovery under Laravel 13. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR aims to restore compatibility with newer Symfony / Laravel versions (notably Symfony 8’s Command::configure(): void) and simultaneously performs a broad upgrade/refactor of the package toward newer Filament APIs, including updated action handling, asset registration, frontend build tooling, and generator commands.
Changes:
- Updates artisan generator commands to use
configure(): voidand modern Symfony Console / Filament command tooling. - Refactors tree pages/widgets/actions to newer Filament Actions/Schemas APIs, adding toolbar actions support and updated Blade components.
- Replaces the frontend build pipeline (Tailwind 4 + esbuild, new asset registration) and adds/updates project tooling (PHPUnit, PHPStan, GitHub workflows, translations).
Reviewed changes
Copilot reviewed 106 out of 127 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| webpack.mix.js | Removes Laravel Mix build config. |
| tailwind.config.js | Removes Tailwind config (moving to Tailwind v4 CLI workflow). |
| stubs/TreeWidget.stub | Removes legacy stub-based widget generator template. |
| stubs/TreeResourcePage.stub | Removes legacy stub-based resource page generator template. |
| stubs/TreePage.stub | Removes legacy stub-based page generator template. |
| src/Widgets/Tree.php | Refactors widget to new BaseWidget/actions APIs; adds create schema hook and translatable driver stub. |
| src/Widgets/BaseWidget.php | Adds shared widget base implementing Filament Actions + Forms. |
| src/Support/Utils.php | Adjusts default parent id typing and nested array logic; imports Collection. |
| src/Resources/Pages/TreePage.php | Refactors resource tree page to use Filament Actions/Schemas and shared TreePageTrait. |
| src/Pages/TreePage.php | Replaces large in-class implementation with TreePageTrait. |
| src/Macros/BlueprintMarcos.php | Tweaks blueprint macro indexes/defaults for tree columns. |
| src/Forms/Components/Tree.php | Refactors form component for Filament Schemas + relationship/node loading behavior. |
| src/FilamentTreeServiceProvider.php | Migrates to PackageServiceProvider and registers Filament assets via FilamentAsset. |
| src/Contract/HasTree.php | Expands interface and adds translatable content driver method requirement. |
| src/Concern/TreeRecords/Translatable.php | Updates action imports/types for new Filament Actions. |
| src/Concern/TreeRecords/HasActiveLocaleSwitcher.php | Reworks locale resolution with panel plugin fallback. |
| src/Concern/TreePageTrait.php | Introduces shared tree page logic extracted from old page class. |
| src/Concern/SupportTranslation.php | Minor whitespace cleanup. |
| src/Concern/ModelTree.php | Refactors fillable initialization and delete cascade; adds stronger typing/imports. |
| src/Concern/InteractWithTree.php | Updates boot logic, adds description hook, root key hook, and refresh dispatch. |
| src/Concern/HasTranslatableRecords.php | Updates typing and minor logic cleanup. |
| src/Concern/HasRecords.php | Adds Livewire #[On('refreshTree')] attribute and typing tweaks. |
| src/Concern/HasEmptyState.php | Import ordering cleanup. |
| src/Concern/HasActions.php | Major refactor to integrate with Filament Actions resolution/mounting. |
| src/Concern/BelongsToLivewire.php | Adds forwarding for translatable content driver. |
| src/Concern/Actions/TreeActionTrait.php | Adds action trait integrating tree context into Filament actions. |
| src/Concern/Actions/HasTree.php | Adds a small interface to standardize tree() on actions/groups. |
| src/Components/Tree.php | Adds toolbar actions support and action lookup helpers. |
| src/Commands/MakeTreeWidgetCommand.php | Rewrites widget generator command using Symfony Console configure() and Filament generator helpers. |
| src/Commands/FileGenerators/TreeWidgetClassGenerator.php | Adds class generator for tree widgets using Nette PhpGenerator. |
| src/Commands/FileGenerators/TreePageClassGenerator.php | Adds class generator for tree pages (non-resource). |
| src/Commands/FileGenerators/ResourceTreePageClassGenerator.php | Adds class generator for resource-based tree pages. |
| src/Commands/FileGenerators/Concerns/CanGenerateTreeProperties.php | Adds shared generator concern for tree properties. |
| src/Commands/FileGenerators/Concerns/CanGenerateTreeMethods.php | Adds shared generator concern for common page/widget methods. |
| src/Commands/FileGenerators/Concerns/CanGenerateModelProperty.php | Adds shared generator concern for model property/imports. |
| src/Actions/ViewAction.php | Replaces custom action with Filament base action + TreeActionTrait. |
| src/Actions/Modal/Action.php | Deprecates custom modal action in favor of Filament actions; keeps tree binding. |
| src/Actions/EditAction.php | Replaces custom action with Filament base action + TreeActionTrait. |
| src/Actions/DeleteAction.php | Replaces custom action with Filament base action + TreeActionTrait. |
| src/Actions/CreateAction.php | Adds CreateAction wrapper using Filament base action + TreeActionTrait. |
| src/Actions/ActionGroup.php | Switches to Filament ActionGroup and propagates tree() to children. |
| src/Actions/Action.php | Switches to Filament Action base + TreeActionTrait/HasTree. |
| resources/views/widgets/tree.blade.php | Updates widget wrapper component namespace and includes Filament action modals. |
| resources/views/tree/scripts.blade.php | Removes jQuery inline script include (replaced by Alpine component + assets). |
| resources/views/pages/tree.blade.php | Updates page wrapper component namespace. |
| resources/views/forms/tree/option-item.blade.php | Removes legacy recursive option rendering partial (replaced by components). |
| resources/views/forms/tree.blade.php | Refactors tree form UI (expand/collapse, select all) using Alpine + new components. |
| resources/views/components/tree/list.blade.php | Passes record description into item component. |
| resources/views/components/tree/item.blade.php | Refactors tree row markup and delegates display to item-display component. |
| resources/views/components/tree/item-display.blade.php | Adds sanitized title/description display component. |
| resources/views/components/tree/index.blade.php | Migrates to Alpine-loaded tree component, adds toolbar actions, removes custom modal. |
| resources/views/components/modal/subheading.blade.php | Switches modal subheading to Filament v4+ dynamic modal description component. |
| resources/views/components/modal/index.blade.php | Replaces custom modal wrapper with Filament modal.index component. |
| resources/views/components/modal/heading.blade.php | Switches modal heading to Filament modal.heading component. |
| resources/views/components/modal/actions.blade.php | Switches modal actions to Filament actions component. |
| resources/views/components/forms/tree/item.blade.php | Adds a reusable checkbox tree node component. |
| resources/views/components/forms/tree/group.blade.php | Adds recursive group component for tree nodes. |
| resources/views/components/actions/index.blade.php | Switches to Filament actions renderer and filters visible actions. |
| resources/views/components/actions/action.blade.php | Updates action rendering to align with Filament action props/handlers. |
| resources/views/actions/modal/actions/button-action.blade.php | Deprecates legacy modal button template. |
| resources/views/actions/link-action.blade.php | Deprecates legacy link action template. |
| resources/views/actions/icon-button-action.blade.php | Deprecates legacy icon button action template. |
| resources/views/actions/grouped-action.blade.php | Deprecates legacy grouped action template. |
| resources/views/actions/group.blade.php | Deprecates legacy action group template. |
| resources/views/actions/button-action.blade.php | Deprecates legacy button action template. |
| resources/lang/zh-HK/filament-tree.php | Minor formatting cleanup in existing translation file. |
| resources/lang/zh-Hant/filament-tree.php | Minor formatting cleanup in existing translation file. |
| resources/lang/zh_TW/filament-tree.php | Adds zh_TW translations. |
| resources/lang/zh_TW/.gitkeep | Keeps zh_TW lang directory in git. |
| resources/lang/zh_HK/filament-tree.php | Adds zh_HK translations (underscore locale folder). |
| resources/lang/zh_HK/.gitkeep | Keeps zh_HK lang directory in git. |
| resources/lang/zh_Hant/filament-tree.php | Adds zh_Hant translations (underscore locale folder). |
| resources/lang/zh_Hant/.gitkeep | Keeps zh_Hant lang directory in git. |
| resources/lang/zh_Hans/filament-tree.php | Adds zh_Hans translations. |
| resources/lang/zh_Hans/.gitkeep | Keeps zh_Hans lang directory in git. |
| resources/lang/zh_CN/filament-tree.php | Minor formatting cleanup in existing zh_CN translation file. |
| resources/lang/zh_CN/.gitkeep | Keeps zh_CN lang directory in git. |
| resources/lang/tr/filament-tree.php | Adds Turkish translations. |
| resources/lang/pt_PT/filament-tree.php | Adds Portuguese (Portugal) translations. |
| resources/lang/pt_BR/filament-tree.php | Adds Portuguese (Brazil) translations. |
| resources/lang/nl/filament-tree.php | Adds Dutch translations. |
| resources/lang/it/filament-tree.php | Adds Italian translations. |
| resources/lang/id_ID/filament-tree.php | Adds Indonesian translations. |
| resources/lang/fr/filament-tree.php | Adds French translations. |
| resources/lang/fa/filament-tree.php | Adds Persian translations. |
| resources/lang/fa/.gitkeep | Keeps fa lang directory in git. |
| resources/lang/es/filament-tree.php | Adds Spanish translations. |
| resources/lang/en/filament-tree.php | Minor formatting cleanup in existing English translation file. |
| resources/lang/de/filament-tree.php | Adds German translations. |
| resources/lang/de/.gitkeep | Keeps de lang directory in git. |
| resources/lang/az/filament-tree.php | Adds Azerbaijani translations. |
| resources/lang/ar/filament-tree.php | Adds Arabic translations. |
| resources/js/plugin.js | Removes old jQuery plugin entrypoint. |
| resources/js/jquery.nestable.js | Refactors nestable plugin and adds RTL positioning support. |
| resources/js/filament-tree.js | Adds Alpine init entrypoint for tree component. |
| resources/js/components/filament-tree-component.js | Adds Alpine + jQuery-based nestable wrapper component with save/expand/collapse actions. |
| resources/dist/filament-tree.css | Rebuilds distribution CSS (now includes Tailwind v4 output + custom styles). |
| resources/css/plugin.css | Updates Tailwind v4 import strategy and sources. |
| resources/css/jquery.nestable.css | Formatting cleanup, RTL and dark mode tweaks, drag styling updates. |
| resources/css/custom-nestable-item.css | Adds Tailwind @apply-based styling for tree items. |
| resources/css/button.css | Adds RTL-aware button group rounding logic. |
| postcss.config.js | Updates PostCSS plugins to Tailwind v4 postcss package. |
| phpunit.xml.dist | Adds PHPUnit 10+ config. |
| phpstan.neon.dist | Adds PHPStan config referencing baseline and build tmp dirs. |
| package.json | Updates build scripts to Tailwind v4 CLI + esbuild build script; bumps deps; sets type: module. |
| config/filament-tree.php | Minor formatting cleanup; retains config keys. |
| composer.json | Updates PHP/Filament constraints and dev tooling; adds new composer scripts. |
| CHANGELOG.md | Adds changelog file content. |
| bin/build.js | Adds esbuild build script to compile JS outputs. |
| .gitignore | Updates ignored files/dirs. |
| .github/workflows/update-changelog.yml | Adds workflow to update changelog on releases. |
| .github/workflows/generate-release-note.yml | Adds workflow to generate draft releases from tags. |
| .github/workflows/fix-php-code-style-issues.yml | Adds workflow to auto-fix PHP styling using Pint. |
| .github/release.yml | Adds GitHub release note categorization config. |
| .github/ISSUE_TEMPLATE/config.yml | Adds issue template config with contact links. |
| .github/ISSUE_TEMPLATE/bug.yml | Adds structured bug report issue template. |
| .github/dependabot.yml | Adds Dependabot config for GitHub Actions updates. |
| .github/copilot-instructions.md | Adds repository-specific Copilot guidance. |
| .github/CONTRIBUTING.md | Adds contributing guide. |
| .gitattributes | Adds export-ignore rules for distribution packaging. |
| "require": { | ||
| "php": "^8.0", | ||
| "filament/filament": "^2.0", | ||
| "spatie/laravel-package-tools": "^1.13.5" | ||
| "php": "^8.1", | ||
| "filament/filament": "^5.0", | ||
| "spatie/laravel-package-tools": "^1.15.0" | ||
| }, |
There was a problem hiding this comment.
The PR description says this change is limited to adding a : void return type for Symfony 8 compatibility, but this PR also bumps the package requirements to PHP ^8.1 and Filament ^5.0 (and includes a large Filament/actions refactor across the codebase). Please update the PR title/description (or split into separate PRs) so reviewers/users understand the breaking upgrade scope.
| class Tree extends BaseWidget implements HasTree | ||
| { | ||
| use Concern\InteractWithTree; | ||
| use InteractsWithForms; | ||
| use InteractWithTree; | ||
|
|
||
| protected static string $view = 'filament-tree::widgets.tree'; | ||
| protected string $view = 'filament-tree::widgets.tree'; | ||
|
|
There was a problem hiding this comment.
SolutionForest\FilamentTree\Contract\HasTree now requires makeFilamentTranslatableContentDriver(), but this widget implements HasTree without providing that method (it instead defines makeTranslatableContentDriver()). This will cause a fatal error on class load. Implement the interface method (or rename the existing method / adjust the interface) so Tree satisfies HasTree.
| public function makeTranslatableContentDriver(): ?TranslatableContentDriver | ||
| { | ||
| return null; | ||
| } |
There was a problem hiding this comment.
makeTranslatableContentDriver() does not match the HasTree::makeFilamentTranslatableContentDriver() signature. As written, Tree still won't satisfy the HasTree interface. Consider either adding a makeFilamentTranslatableContentDriver() method that delegates to this one, or renaming this method to match the interface.
| abstract class TreePage extends Page implements HasTree | ||
| { | ||
| use Concern\InteractWithTree; | ||
| use TreePageTrait; | ||
|
|
||
| protected static string $view = 'filament-tree::pages.tree'; | ||
|
|
||
| protected static string $viewIdentifier = 'tree'; | ||
|
|
||
| protected static string $model; | ||
|
|
||
| protected static int $maxDepth = 999; | ||
|
|
||
| public static function tree(Tree $tree): Tree | ||
| { | ||
| return $tree; | ||
| } | ||
|
|
||
| public static function getMaxDepth(): int | ||
| { | ||
| return static::$maxDepth; | ||
| } | ||
|
|
||
| protected function model(string $model): static | ||
| { | ||
| static::$model = $model; | ||
|
|
||
| return $this; | ||
| } | ||
|
|
||
| public function getModel(): string | ||
| { | ||
| return static::$model ?? class_basename(static::class); | ||
| } | ||
|
|
||
| protected function hasCreateAction(): bool | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| protected function hasDeleteAction(): bool | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| protected function hasEditAction(): bool | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| protected function hasViewAction(): bool | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| protected function getCreateAction(): CreateAction | ||
| { | ||
| return CreateAction::make(); | ||
| } | ||
|
|
||
| protected function getDeleteAction(): Actions\DeleteAction | ||
| { | ||
| return Actions\DeleteAction::make(); | ||
| } | ||
|
|
||
| protected function getEditAction(): Actions\EditAction | ||
| { | ||
| return Actions\EditAction::make(); | ||
| } | ||
|
|
||
| protected function getViewAction(): Actions\ViewAction | ||
| { | ||
| return Actions\ViewAction::make(); | ||
| } | ||
|
|
||
| protected function configureAction(Action $action): void | ||
| { | ||
| match (true) { | ||
| $action instanceof CreateAction => $this->configureCreateAction($action), | ||
| default => null, | ||
| }; | ||
| } | ||
|
|
||
| protected function configureTreeAction(Actions\Action $action): void | ||
| { | ||
| match (true) { | ||
| $action instanceof Actions\DeleteAction => $this->configureDeleteAction($action), | ||
| $action instanceof Actions\EditAction => $this->configureEditAction($action), | ||
| $action instanceof Actions\ViewAction => $this->configureViewAction($action), | ||
| default => null, | ||
| }; | ||
| } | ||
|
|
||
| protected function configureCreateAction(CreateAction $action): CreateAction | ||
| { | ||
| $action->livewire($this); | ||
|
|
||
| $schema = $this->getCreateFormSchema(); | ||
|
|
||
| if (empty($schema)) { | ||
| $schema = $this->getFormSchema(); | ||
| } | ||
|
|
||
| $action->form($schema); | ||
|
|
||
| $action->model($this->getModel()); | ||
|
|
||
| $this->afterConfiguredCreateAction($action); | ||
|
|
||
| return $action; | ||
| } | ||
|
|
||
| protected function configureDeleteAction(Actions\DeleteAction $action): Actions\DeleteAction | ||
| { | ||
| $action->tree($this->getCachedTree()); | ||
|
|
||
| $this->afterConfiguredDeleteAction($action); | ||
|
|
||
| return $action; | ||
| } | ||
|
|
||
| protected function configureEditAction(Actions\EditAction $action): Actions\EditAction | ||
| { | ||
| $action->tree($this->getCachedTree()); | ||
|
|
||
| $schema = $this->getEditFormSchema(); | ||
|
|
||
| if (empty($schema)) { | ||
| $schema = $this->getFormSchema(); | ||
| } | ||
|
|
||
| $action->form($schema); | ||
|
|
||
| $action->model($this->getModel()); | ||
|
|
||
| $action->mutateFormDataBeforeSaveUsing(fn (array $data) => $this->mutateFormDataBeforeSave($data)); | ||
|
|
||
| $this->afterConfiguredEditAction($action); | ||
|
|
||
| return $action; | ||
| } | ||
|
|
||
| protected function configureViewAction(Actions\ViewAction $action): Actions\ViewAction | ||
| { | ||
| $action->tree($this->getCachedTree()); | ||
|
|
||
| $schema = $this->getViewFormSchema(); | ||
|
|
||
| if (empty($schema)) { | ||
| $schema = $this->getFormSchema(); | ||
| } | ||
|
|
||
| $action->form($schema); | ||
|
|
||
| $action->model($this->getModel()); | ||
|
|
||
| $this->afterConfiguredViewAction($action); | ||
|
|
||
| return $action; | ||
| } | ||
|
|
||
| protected function afterConfiguredCreateAction(CreateAction $action): CreateAction | ||
| { | ||
| return $action; | ||
| } | ||
|
|
||
| protected function afterConfiguredDeleteAction(Actions\DeleteAction $action): Actions\DeleteAction | ||
| { | ||
| return $action; | ||
| } | ||
|
|
||
| protected function afterConfiguredEditAction(Actions\EditAction $action): Actions\EditAction | ||
| { | ||
| return $action; | ||
| } | ||
|
|
||
| protected function afterConfiguredViewAction(Actions\ViewAction $action): Actions\ViewAction | ||
| { | ||
| return $action; | ||
| } | ||
|
|
||
| protected function getFormSchema(): array | ||
| { | ||
| return []; | ||
| } | ||
|
|
||
| protected function getCreateFormSchema(): array | ||
| { | ||
| return []; | ||
| } | ||
|
|
||
| protected function getViewFormSchema(): array | ||
| { | ||
| return []; | ||
| } | ||
|
|
||
| protected function getEditFormSchema(): array | ||
| { | ||
| return []; | ||
| } | ||
|
|
||
| protected function getTreeActions(): array | ||
| { | ||
| return array_merge( | ||
| ($this->hasEditAction() ? [$this->getEditAction()] : []), | ||
| ($this->hasViewAction() ? [$this->getViewAction()] : []), | ||
| ($this->hasDeleteAction() ? [$this->getDeleteAction()] : []), | ||
| ); | ||
| } | ||
|
|
||
| protected function getActions(): array | ||
| { | ||
| return array_merge( | ||
| ($this->hasCreateAction() ? [$this->getCreateAction()] : []), | ||
| ); | ||
| } | ||
|
|
||
| protected function mutateFormDataBeforeSave(array $data): array | ||
| { | ||
| return $data; | ||
| } | ||
|
|
||
| protected function callHook(string $hook): void | ||
| { | ||
| if (! method_exists($this, $hook)) { | ||
| return; | ||
| } | ||
|
|
||
| $this->{$hook}(); | ||
| } | ||
| protected string $view = 'filament-tree::pages.tree'; |
There was a problem hiding this comment.
SolutionForest\FilamentTree\Pages\TreePage implements HasTree, but it doesn't implement the new makeFilamentTranslatableContentDriver() method required by the interface (and TreePageTrait doesn't provide it either). This will trigger a fatal error on class load. Add the missing method (likely returning null by default).
| abstract class TreePage extends BasePage implements HasTree | ||
| { | ||
| use UsesResourceForm; | ||
|
|
||
| protected static ?string $breadcrumb = null; | ||
| use TreePageTrait { | ||
| TreePageTrait::getViewFormSchema as protected traitGetViewFormSchema; | ||
| TreePageTrait::configureDeleteAction as protected traitConfigureDeleteAction; | ||
| TreePageTrait::configureEditAction as protected traitConfigureEditAction; | ||
| TreePageTrait::configureViewAction as protected traitConfigureViewAction; | ||
| TreePageTrait::configureCreateAction as protected traitConfigureCreateAction; | ||
| } | ||
|
|
||
| protected static string $resource; | ||
| protected string $view = 'filament-tree::pages.tree'; |
There was a problem hiding this comment.
SolutionForest\FilamentTree\Resources\Pages\TreePage implements HasTree, but does not implement makeFilamentTranslatableContentDriver() required by the interface (and the used trait doesn’t define it). This will cause a fatal error on class load. Add the missing method (default null return is fine).
| @@ -38,7 +40,7 @@ public static function defaultChildrenKeyName(): string | |||
| } | |||
There was a problem hiding this comment.
defaultChildrenKeyName() reads filament-tree.default_children_key, but the published config uses default_children_key_name. As-is, the config value will never be respected. Align the config key name (either update this method to read default_children_key_name, or rename the config entry).
| public static function defaultParentId(): ?int | ||
| { | ||
| return (int) config('filament-tree.default_parent_id', -1); | ||
| return config('filament-tree.default_parent_id', -1); | ||
| } |
There was a problem hiding this comment.
defaultParentId() is declared to return ?int, but it returns config(...) without casting. If a consumer sets default_parent_id via .env, it may be a string (e.g. "-1"), which will throw a TypeError at runtime. Cast to int (or widen the return type) to match the possible config value types.
| @@ -49,17 +51,22 @@ public static function buildNestedArray( | |||
| { | |||
| $branch = []; | |||
| $parentId = is_numeric($parentId) ? intval($parentId) : $parentId; | |||
| if (blank($parentId)) { | |||
| $parentId = self::defaultParentId(); | |||
| } | |||
| // if (blank($parentId)) { | |||
| // $parentId = self::defaultParentId(); | |||
| // } | |||
| $primaryKeyName = $primaryKeyName ?: 'id'; | |||
| $parentKeyName = $parentKeyName ?: static::parentColumnName(); | |||
| $childrenKeyName = $childrenKeyName ?: static::defaultChildrenKeyName(); | |||
|
|
|||
| $nodeGroups = collect($nodes)->groupBy(fn ($node) => $node[$parentKeyName])->sortKeys(); | |||
| foreach ($nodeGroups as $pk => $nodeGroup) { | |||
| $pk = is_numeric($pk) ? intval($pk) : $pk; | |||
| if ($pk === $parentId) { | |||
| if ( | |||
| ($pk === $parentId) | |||
| // Allow parentId is nullable or negative number | |||
| // https://github.com/solutionforest/filament-tree/issues/28 | |||
| || (($pk === '' || $pk <= 0) && $parentId <= 0) | |||
| ) { | |||
There was a problem hiding this comment.
buildNestedArray() now allows $parentId to remain null (the blank() fallback is commented out), but the comparison ($parentId <= 0) will throw a TypeError when $parentId is null. Either restore the fallback to defaultParentId() when blank/null, or guard the numeric comparisons so the default parameter value is safe to use.
| x-data="treeNestableComponent({ | ||
| containerKey: {{ $containerKey }}, | ||
| maxDepth: {{ $maxDepth }} | ||
| })"> |
There was a problem hiding this comment.
In the x-data object, containerKey: {{ $containerKey }} renders as an unquoted string, which will be treated as a JS identifier and break Alpine initialization (e.g. containerKey: filament_tree_container_abc). Pass it as a JS string (e.g. via @js($containerKey)), and consider passing an ID selector ('#' + $containerKey) since the JS currently does $(containerKey).
| init: function () { | ||
|
|
||
| // Used for jQuery event | ||
| let nestedTreeElement = $(this.containerKey); | ||
| this.nestedTreeElement = nestedTreeElement; | ||
|
|
||
| let nestedTree = this.compile(this.nestedTreeElement, { | ||
| group: containerKey, | ||
| maxDepth: maxDepth, | ||
| expandBtnHTML: '', | ||
| collapseBtnHTML: '', | ||
| }); |
There was a problem hiding this comment.
nestedTreeElement = $(this.containerKey) assumes containerKey is a valid selector. With the current Blade template it’s an element id like filament_tree_container_..., so jQuery will look for a <filament_tree_container_...> tag and return an empty set. Use $('#' + this.containerKey) (or pass containerKey in as '#...') so the plugin is initialized against the correct element.
Problem
Symfony 8 adds an explicit
voidreturn type toCommand::configure(). PHP enforces return type covariance, so any subclass overridingconfigure()without thevoidreturn type declaration causes a fatal error on class load:This breaks
php artisan package:discover(and anything that loads these command classes) when using Laravel 13, which ships with Symfony 8.Closes #102
Fix
Add
: voidreturn type toconfigure()in both affected command classes:MakeTreePageCommandMakeTreeWidgetCommandTest
Should complete without fatal errors.