Files
fotospiel-app/app/Filament/Clusters/WeeklyOps/Resources/TaskCollections/RelationManagers/TasksRelationManager.php
Codex Agent 750acb0bec
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Allow task attach search across global tasks
2026-01-19 21:42:09 +01:00

128 lines
4.6 KiB
PHP

<?php
namespace App\Filament\Clusters\WeeklyOps\Resources\TaskCollections\RelationManagers;
use App\Models\Task;
use Filament\Actions\AttachAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DetachAction;
use Filament\Actions\DetachBulkAction;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Arr;
class TasksRelationManager extends RelationManager
{
protected static string $relationship = 'tasks';
protected static ?string $inverseRelationship = 'taskCollections';
public function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('title')
->label(__('admin.tasks.table.title'))
->getStateUsing(fn (Task $record) => $this->formatTaskTitle($record->title))
->searchable(['title->de', 'title->en'])
->limit(60),
TextColumn::make('emotion.name')
->label(__('admin.tasks.fields.emotion'))
->getStateUsing(function (Task $record) {
$value = optional($record->emotion)->name;
if (is_array($value)) {
$locale = app()->getLocale();
return $value[$locale] ?? ($value['de'] ?? ($value['en'] ?? ''));
}
return (string) ($value ?? '');
})
->sortable(),
TextColumn::make('difficulty')
->label(__('admin.tasks.fields.difficulty.label'))
->badge(),
IconColumn::make('is_active')
->label(__('admin.tasks.table.is_active'))
->boolean(),
TextColumn::make('sort_order')
->label(__('admin.tasks.table.sort_order'))
->sortable(),
])
->headerActions([
AttachAction::make()
->recordTitle(fn (Task $record) => $this->formatTaskTitle($record->title))
->recordSelectOptionsQuery(fn (Builder $query): Builder => $query->whereNull('tenant_id'))
->multiple()
->after(function (array $data): void {
$collection = $this->getOwnerRecord();
$recordIds = Arr::wrap($data['recordId'] ?? []);
if ($recordIds === []) {
return;
}
$collection->reassignTasks($recordIds);
}),
])
->recordActions([
DetachAction::make()
->after(function (?Task $record): void {
if (! $record) {
return;
}
$collectionId = $this->getOwnerRecord()->getKey();
if ($record->collection_id === $collectionId) {
$record->update(['collection_id' => null]);
}
}),
])
->toolbarActions([
BulkActionGroup::make([
DetachBulkAction::make()
->after(function (Collection $records): void {
$collectionId = $this->getOwnerRecord()->getKey();
$ids = $records
->filter(fn (Task $record) => $record->collection_id === $collectionId)
->pluck('id')
->all();
if ($ids === []) {
return;
}
Task::query()
->whereIn('id', $ids)
->update(['collection_id' => null]);
}),
]),
]);
}
/**
* @param array<string, string>|string|null $value
*/
protected function formatTaskTitle(array|string|null $value): string
{
if (is_array($value)) {
$locale = app()->getLocale();
return $value[$locale]
?? ($value['de'] ?? ($value['en'] ?? Arr::first($value) ?? ''));
}
if (is_string($value)) {
return $value;
}
return '';
}
}