Generate a pdf from BulkAction values

Tables\Actions\Action::make('pdf')
->icon('heroicon-o-document-download')
->color('danger')
->label('PDF')
->url(fn (List $record) => route('list.pdf.download', $record))
->openUrlInNewTab(),
Tables\Actions\Action::make('pdf')
->icon('heroicon-o-document-download')
->color('danger')
->label('PDF')
->url(fn (List $record) => route('list.pdf.download', $record))
->openUrlInNewTab(),
Hello, how can y build the same document from BulkAction values with an intermediate form to set some other properties?
Tables\Actions\BulkAction::make('stickers')
->action(function (Collection $records, array $data): void {
????
????
????route('stickers.pdf.download', $data);
})
->label('Stickers')
->color('success')
->icon('heroicon-s-printer')
->modalWidth('sm')
->form([
Forms\Components\TextInput::make('start')
->numeric()
->minValue(1)
->maxValue(8)
->label('Start')
])
]);
Tables\Actions\BulkAction::make('stickers')
->action(function (Collection $records, array $data): void {
????
????
????route('stickers.pdf.download', $data);
})
->label('Stickers')
->color('success')
->icon('heroicon-s-printer')
->modalWidth('sm')
->form([
Forms\Components\TextInput::make('start')
->numeric()
->minValue(1)
->maxValue(8)
->label('Start')
])
]);
20 Replies
toeknee
toeknee2y ago
Sorry what do you mean?
Pasteko
PastekoOP2y ago
I need to do this but with BulkAction.
Tables\Actions\Action::make('pdf')
->icon('heroicon-o-document-download')
->color('danger')
->label('PDF')
->url(fn (List $record) => route('list.pdf.download', $record))
->openUrlInNewTab(),
Tables\Actions\Action::make('pdf')
->icon('heroicon-o-document-download')
->color('danger')
->label('PDF')
->url(fn (List $record) => route('list.pdf.download', $record))
->openUrlInNewTab(),
Since ->url and ->openUrlInNewTab() are not possible with BulkAction, what can I do to call the view with the selected records?
awcodes
awcodes2y ago
I would truly re-think this approach. Bulk actions run on every record selected. So it the user selected 50 items and ran your bulk action it would open 50 tabs and bog down your server trying to generate 50 pdfs at the same time.
Pasteko
PastekoOP2y ago
That's probably what I have to do, but how can I generate one pdf with the 50 items? Is there another way to select them?
awcodes
awcodes2y ago
Could probably do a custom bulk action and use the items to generate one pdf. Then you could redirect() to the url. But there’s not a good way to open it in a new tab from the backend. You can emit a browser event and use a Js listener to open a url, but it has some caveats. https://developer.mozilla.org/en-US/docs/Web/API/Window/open
Window: open() method - Web APIs | MDN
The open() method of the Window interface loads a specified resource into a new or existing browsing context (that is, a tab, a window, or an iframe) under a specified name.
Pasteko
PastekoOP2y ago
Thank you, I'm gonna try to generate the pdf first.
Kenneth Sese
Kenneth Sese2y ago
Generate the pdf then download:
->action(function (Collection $records) {
$zip = GenerateZipOfStatements::generate($records);
return response()->streamDownload(function () use ($zip) {
$zip->process();
}, $zip->getName());
})
->action(function (Collection $records) {
$zip = GenerateZipOfStatements::generate($records);
return response()->streamDownload(function () use ($zip) {
$zip->process();
}, $zip->getName());
})
Pasteko
PastekoOP2y ago
Hello, this is kinda working, the problem for me is that it asks where to save the file, what can I change to show the pdf instead of download? Resource
Tables\Actions\BulkAction::make('labels')
->action(function (Collection $records, array $data) {
$pdf = (new PdfController)->labels($records, $data);
return response()->streamDownload(
fn () => print($pdf),
"filename.pdf"
);
})
->label('Page d\'étiquettes')
->color('success')
->icon('heroicon-s-printer')
->modalWidth('sm')
->form([
Forms\Components\TextInput::make('number')
->numeric()
->minValue(1)
->maxValue(8)
->default(1)
->label('Étiquette de départ')
])
Tables\Actions\BulkAction::make('labels')
->action(function (Collection $records, array $data) {
$pdf = (new PdfController)->labels($records, $data);
return response()->streamDownload(
fn () => print($pdf),
"filename.pdf"
);
})
->label('Page d\'étiquettes')
->color('success')
->icon('heroicon-s-printer')
->modalWidth('sm')
->form([
Forms\Components\TextInput::make('number')
->numeric()
->minValue(1)
->maxValue(8)
->default(1)
->label('Étiquette de départ')
])
Controller
public function labels($records, $data)
{
$title = [0 => 'M.', 1 => 'Mme'];
$pdf = App::make('dompdf.wrapper');
$pdf->set_paper('A4', 'portrait');
$pdf->loadView('pdf.labels', compact('records'));
return $pdf->stream();
}
public function labels($records, $data)
{
$title = [0 => 'M.', 1 => 'Mme'];
$pdf = App::make('dompdf.wrapper');
$pdf->set_paper('A4', 'portrait');
$pdf->loadView('pdf.labels', compact('records'));
return $pdf->stream();
}
Kenneth Sese
Kenneth Sese2y ago
I don't think that's possible. In a normal action, you could use ->url() and then redirect to your controller. But BulkActions don't have the url() method which makes sense because you'd open a bunch of URLs. Might be another way, but not that I'm aware of. Sorry
Pasteko
PastekoOP2y ago
Thanks for your help.
awcodes
awcodes2y ago
Maybe you could send it to a job, then when that’s done send a notification with the link in the body of the notification. And set the notification to be persistent so it doesn’t disappear. Then the user can keep working until it’s done and open it when it’s ready.
Kenneth Sese
Kenneth Sese2y ago
oooooooo...I like it!
awcodes
awcodes2y ago
Fair amount of moving parts, but might be the best bet for this use case. Imagine the server crashing because some selected 100s of records.
Kenneth Sese
Kenneth Sese2y ago
agree
awcodes
awcodes2y ago
Or worse, someone sitting on a loading spinner for 15 minutes. Lol.
toeknee
toeknee2y ago
I actually ended up putting my PDF generator as a function within the Model and just call it that way and provide a path for it, looping through the records and add them to a zip and stream it to download.
Kenneth Sese
Kenneth Sese2y ago
I believe that’s similar to what I had suggested at first, but OP wants to be able to view the generated PDF, not download it.
toeknee
toeknee2y ago
Ahh, from a bulk action just open in a new tab?
Kenneth Sese
Kenneth Sese2y ago
Url() doesn’t exist in bulk actions, which makes sense since it’d open a bunch of urls. That’s why Adam suggested that round about way to present a Url in a notification. Maybe we’re overlooking something?
toeknee
toeknee2y ago
->url() doesn't but you can trigger a url response if memory serves me right but I could be wrong
Want results from more Discord servers?
Add your server