-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(filament): added custom BelongsTo field & BelongsToColumn (#713)
- Loading branch information
Showing
75 changed files
with
547 additions
and
392 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Concerns\Filament\Actions; | ||
|
||
use App\Models\Admin\ActionLog; | ||
use Illuminate\Database\Eloquent\Relations\MorphMany; | ||
|
||
/** | ||
* Trait ModelHasActionLogs. | ||
*/ | ||
trait ModelHasActionLogs | ||
{ | ||
/** | ||
* Get the action logs for the model. | ||
* | ||
* @return MorphMany | ||
*/ | ||
public function actionlogs(): MorphMany | ||
{ | ||
return $this->morphMany(ActionLog::class, 'actionable'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Filament\Components\Columns; | ||
|
||
use App\Filament\Resources\BaseResource; | ||
use App\Models\BaseModel; | ||
use Filament\Support\Enums\FontWeight; | ||
use Illuminate\Database\Eloquent\Model; | ||
use Illuminate\Support\Arr; | ||
use Illuminate\Support\Str; | ||
|
||
/** | ||
* Class BelongsToColumn. | ||
*/ | ||
class BelongsToColumn extends TextColumn | ||
{ | ||
protected ?BaseResource $resource = null; | ||
|
||
/** | ||
* This should reload after every method. | ||
* | ||
* @return void | ||
*/ | ||
public function reload(): void | ||
{ | ||
$relation = explode('.', $this->getName())[0]; | ||
|
||
$this->placeholder('-'); | ||
$this->label($this->resource->getModelLabel()); | ||
$this->tooltip(fn (BelongsToColumn $column) => is_array($column->getState()) ? null : $column->getState()); | ||
$this->weight(FontWeight::SemiBold); | ||
$this->html(); | ||
$this->url(function (BaseModel|Model $record) use ($relation) { | ||
foreach (explode('.', $relation) as $element) { | ||
$record = Arr::get($record, $element); | ||
if ($record === null) return null; | ||
} | ||
|
||
$this->formatStateUsing(function () use ($record) { | ||
$name = $record->getName(); | ||
$nameLimited = Str::limit($name, $this->getCharacterLimit() ?? 100); | ||
return "<p style='color: rgb(64, 184, 166);'>{$nameLimited}</p>"; | ||
}); | ||
|
||
return (new $this->resource)::getUrl('view', ['record' => $record]); | ||
}); | ||
} | ||
|
||
/** | ||
* Set the filament resource for the relation. | ||
* | ||
* @param class-string<BaseResource> $resource | ||
* @return static | ||
*/ | ||
public function resource(string $resource): static | ||
{ | ||
$this->resource = new $resource; | ||
$this->reload(); | ||
|
||
return $this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Filament\Components\Fields; | ||
|
||
use App\Enums\Http\Api\Filter\ComparisonOperator; | ||
use App\Filament\Resources\BaseResource; | ||
use App\Models\Auth\User; | ||
use App\Models\BaseModel; | ||
use Filament\Forms\Components\Select as ComponentsSelect; | ||
use Filament\Forms\Form; | ||
use Laravel\Scout\Searchable; | ||
|
||
/** | ||
* Class BelongsTo. | ||
*/ | ||
class BelongsTo extends ComponentsSelect | ||
{ | ||
protected ?BaseResource $resource = null; | ||
protected bool $showCreateOption = false; | ||
|
||
/** | ||
* This should reload after every method. | ||
* | ||
* @return void | ||
*/ | ||
protected function reload(): void | ||
{ | ||
if ($this->showCreateOption && $this->resource !== null) { | ||
$this->createOptionForm(fn (Form $form) => $this->resource::form($form)->getComponents()); | ||
} | ||
|
||
if ($this->resource) { | ||
$this->label($this->resource->getModelLabel()); | ||
} | ||
} | ||
|
||
/** | ||
* Set the filament resource for the relation. | ||
* | ||
* @param class-string<BaseResource> $resource | ||
* @return static | ||
*/ | ||
public function resource(string $resource): static | ||
{ | ||
$this->resource = new $resource; | ||
$this->tryScout($this->resource->getModel()); | ||
$this->reload(); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Determine if the create option is available. The resource is required for this. | ||
* | ||
* @param bool $condition | ||
* @return static | ||
*/ | ||
public function showCreateOption(bool $condition = true): static | ||
{ | ||
$this->showCreateOption = $condition; | ||
$this->reload(); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Make the field searchable and use laravel scout if available. | ||
* | ||
* @param class-string<BaseModel> $model | ||
* @return static | ||
*/ | ||
protected function tryScout(string $model): static | ||
{ | ||
$this->allowHtml(); | ||
$this->searchable(); | ||
$this->getOptionLabelUsing(fn ($state) => static::getSearchLabelWithBlade((new $model)::find($state))); | ||
|
||
if (in_array(Searchable::class, class_uses_recursive($model))) { | ||
return $this | ||
->getSearchResultsUsing(function (string $search) use ($model) { | ||
return (new $model)::search($search) | ||
->take(25) | ||
->get() | ||
->mapWithKeys(fn (BaseModel $model) => [$model->getKey() => static::getSearchLabelWithBlade($model)]) | ||
->toArray(); | ||
}); | ||
} | ||
|
||
return $this | ||
->getSearchResultsUsing(function (string $search) use ($model) { | ||
return (new $model)::query() | ||
->where($this->resource->getRecordTitleAttribute(), ComparisonOperator::LIKE->value, "%$search%") | ||
->take(25) | ||
->get() | ||
->mapWithKeys(fn (BaseModel|User $model) => [$model->getKey() => static::getSearchLabelWithBlade($model)]) | ||
->toArray(); | ||
}); | ||
} | ||
|
||
/** | ||
* Use the blade to make the results. | ||
* | ||
* @param BaseModel|User $model | ||
* @return string | ||
*/ | ||
public static function getSearchLabelWithBlade(BaseModel|User $model): string | ||
{ | ||
return view('filament.components.select') | ||
->with('name', $model->getName()) | ||
->with('subtitle', $model->getSubtitle()) | ||
->with('image', $model instanceof User ? $model->getFilamentAvatarUrl() : null) | ||
->render(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.