To achieve the functionality you're looking for in Filament, you can indeed use the Relation Manager to attach time logs to an invoice. However, to filter and select multiple time logs, you might need to customize the Relation Manager or use a different approach.
Here's a step-by-step solution to create a subform for attaching time logs to an invoice:
- Define the relationships in your Eloquent models if you haven't already done so. For example:
// Invoice model
public function timeLogs()
{
return $this->belongsToMany(TimeLog::class);
}
// TimeLog model
public function invoice()
{
return $this->belongsTo(Invoice::class);
}
-
Create a custom Relation Manager for the
timeLogsrelationship in your Invoice resource. You can do this by running thephp artisan make:filament-resourcecommand and selecting the Invoice model. -
In the generated Relation Manager, override the
getTableQuery()method to filter the time logs based on your criteria (e.g., only show time logs that are not already attached to an invoice).
protected function getTableQuery(): Builder
{
return parent::getTableQuery()
->whereNull('invoice_id'); // Adjust this condition based on your database structure and needs
}
- Customize the table to include a checkbox column for selecting multiple time logs. You can use the
CheckboxColumnprovided by Filament.
protected function getTableColumns(): array
{
return [
// ... other columns
CheckboxColumn::make('selected')
->label('Select')
->sortable(false),
];
}
- Override the
actions()method in your Relation Manager to add a custom action that attaches the selected time logs to the invoice.
protected function getActions(): array
{
return [
// ... other actions
Tables\Actions\Action::make('attachSelected')
->action(function (Invoice $record, array $data): void {
$selectedTimeLogs = collect($data['selected'] ?? [])
->filter(fn ($isSelected) => $isSelected)
->keys();
$record->timeLogs()->attach($selectedTimeLogs);
})
->requiresConfirmation()
->color('success')
->icon('heroicon-s-check'),
];
}
- In your Invoice resource form, add the Relation Manager as a subform.
public function form(Form $form): Form
{
return $form
->schema([
// ... other fields
Forms\Components\BelongsToManyMultiSelect::make('timeLogs')
->relationship('timeLogs', 'name'), // Replace 'name' with the attribute you want to display
]);
}
This is a high-level solution and may require further customization based on your specific needs and the structure of your application. Make sure to adjust the code snippets to fit your actual model attributes and logic.