From af8cddab99adeb604a818cfbcc74bccc0e3d2b5d Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 25 Feb 2024 13:55:33 +0100 Subject: [PATCH] Add possibility to limit max search results & use own model field for search & update documentation --- README.md | 67 +++++++++++++++++++++- config/workflows.php | 4 +- src/Concerns/CanSetupWorkflows.php | 19 +++++- src/Concerns/InteractsWithWorkflow.php | 5 ++ src/Resources/FilamentWorkflowResource.php | 2 +- 5 files changed, 91 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8110e5c..9819615 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,24 @@ This plugin lets you add workflows to your filament app. You can attach triggers and dispatchable actions to your workflows. The plugin will automatically execute the actions when the trigger conditions are met. +## Table of Contents + +- [Images](#images) +- [Installation](#installation) +- [Usage](#usage) + - [Basics](#basics) + - [Add the trait to your model](#add-the-trait-to-your-model) + - [Create an Action](#create-an-action) +- [Configuration](#configuration) + - [Define searchable field](#define-searchable-field) + - [Max Search Results](#max-search-results) +- [Testing](#testing) +- [Changelog](#changelog) +- [Contributing](#contributing) +- [Security Vulnerabilities](#security-vulnerabilities) +- [Credits](#credits) +- [License](#license) + ## Images ![Screenshot 1](.github/images/Basic-Form.png) @@ -58,7 +76,7 @@ class User extends Model { } ``` -### Create a Action +### Create an Action In order to attach an action to your workflows, you will have to create a class within the `App\Jobs\Actions` folder. The class must extend the `BaseAction` class. This requires you to implement the `handle` method. This method will be called when the workflow is executed. The action class is very similar to a job. @@ -88,11 +106,58 @@ class TestAction extends BaseAction { \Log::info($this->user->name . ' was created at ' . $this->user->created_at); } + + // Will be later used in the Logs (coming soon) + public function getActionName(): string + { + return 'Der Hackfleisch hassender Zerhacker'; + } + + public function getActionDescription(): string + { + return 'Schneidet Kopfsalat. Und das nachts :)'; + } + + public function getActionCategory(): string + { + return 'Default-Category'; + } + + public function getActionIcon(): string + { + return 'heroicon-o-adjustments'; + } } ``` That's it. Now you can create and attach actions to your workflows. +## Configuration + +### Define searchable field + +If you don't just want to search for the `id`, you can use the function `getTitleColumnForWorkflowSearch` within your model to search in another field as well. + +```php + public function getTitleColumnForWorkflowSearch(): ?string + { + return 'name'; + } +``` + +### Max Search Results +In case you want to change the max search results for the models, you can publish the config file and change the `workflows.search.max_results` value (defaults to 100). +This can come in handy when you have a lot of models and the search is slow. + +```php + [ + 'max_results' => 100, + ] +]; +``` ## Testing diff --git a/config/workflows.php b/config/workflows.php index ca5d8ed..4bd5811 100644 --- a/config/workflows.php +++ b/config/workflows.php @@ -1,5 +1,7 @@ [ + 'max_results' => 100, + ], ]; diff --git a/src/Concerns/CanSetupWorkflows.php b/src/Concerns/CanSetupWorkflows.php index 931e81a..af86587 100644 --- a/src/Concerns/CanSetupWorkflows.php +++ b/src/Concerns/CanSetupWorkflows.php @@ -3,9 +3,11 @@ namespace Tschucki\FilamentWorkflows\Concerns; use Illuminate\Container\Container; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Collection; use Illuminate\Support\Facades\File; +use Illuminate\Support\Facades\Schema; use Tschucki\FilamentWorkflows\WorkflowActions\BaseAction; trait CanSetupWorkflows @@ -96,14 +98,25 @@ public static function getActionOptions() }); } - public static function getModelOptions(?Model $model) + public static function getModelOptions(?Model $model, string $search = ''): array { if (! $model) { return []; } if (self::modelUsesTrait($model, InteractsWithWorkflow::class)) { - return $model::all()->mapWithKeys(function ($model, $key) { + $iMaxResults = config('workflows.search.results', 100); + $searchableColumn = $model->getTitleColumnForWorkflowSearch(); + + if (! empty($search)) { + return $model::where('id', 'LIKE', '%' . $search . '%')->when($searchableColumn !== null, fn (Builder $query) => $query->orWhere($searchableColumn, 'LIKE', '%' . $search . '%'))->take($iMaxResults)->get()->mapWithKeys(function ($model, $key) { + return [ + $model->getKey() => $model->getTitelAttributeForWorkflow(), + ]; + }); + } + + return $model::take($iMaxResults)->get()->mapWithKeys(function ($model) { return [ $model->getKey() => $model->getTitelAttributeForWorkflow(), ]; @@ -122,7 +135,7 @@ public static function getModelFields(?Model $model): array if (self::modelUsesTrait($model, InteractsWithWorkflow::class)) { $table = $model->getTable(); - return collect(\Schema::getColumnListing($table))->mapWithKeys(function ($column) { + return collect(Schema::getColumnListing($table))->mapWithKeys(function ($column) { return [ $column => $column, ]; diff --git a/src/Concerns/InteractsWithWorkflow.php b/src/Concerns/InteractsWithWorkflow.php index 88bfb9a..8eaa8df 100644 --- a/src/Concerns/InteractsWithWorkflow.php +++ b/src/Concerns/InteractsWithWorkflow.php @@ -45,4 +45,9 @@ public function workflowHasBeenSetup(): bool return $workflowExists && $workflowIsEnabled && $workflowModelId; } + + public function getTitleColumnForWorkflowSearch(): ?string + { + return null; + } } diff --git a/src/Resources/FilamentWorkflowResource.php b/src/Resources/FilamentWorkflowResource.php index 36edcf6..54c0c16 100644 --- a/src/Resources/FilamentWorkflowResource.php +++ b/src/Resources/FilamentWorkflowResource.php @@ -26,7 +26,7 @@ public static function form(Form $form): Form Forms\Components\Tabs::make()->schema([ Forms\Components\Tabs\Tab::make('Basic')->schema([ Forms\Components\Select::make('model_type')->searchable()->reactive()->options(self::getModelTypeOptions())->required(), - Forms\Components\Select::make('model_id')->searchable()->options(fn (Forms\Get $get) => $get('model_type') ? self::getModelOptions(app($get('model_type'))) : [])->nullable(), + Forms\Components\Select::make('model_id')->searchable()->getSearchResultsUsing(fn (Forms\Get $get, ?string $search) => $get('model_type') ? self::getModelOptions(app($get('model_type')), $search) : [])->nullable(), Forms\Components\TextInput::make('title')->autofocus()->required(), Forms\Components\Toggle::make('enabled')->inline(false)->default(true)->required(), Forms\Components\Textarea::make('description')->nullable(),