F
Filament9mo ago
DrByte

trigger multiple downloads from a header Action button

I know I can't have 2 ->action() calls ... but how would I return 2 different Responsable results to fire two separate downloads from clicking the Action button?
Actions\Action::make('export')
->visible(auth()->user()->can('export submissions'))
->color('secondary')
->icon('heroicon-s-arrow-down-tray')
->action(fn () => (new SubmissionsExport)->download('submissions-export-' . date('Y-m-d-i-h-s') . '.xlsx'))
->action(fn () => (new SubmissionsMediaExport)->download('submissions-media-export-' . date('Y-m-d-i-h-s') . '.zip'))
->successNotificationTitle('Exported. Check your Downloads directory.')
->label('Export Submissions'),
Actions\Action::make('export')
->visible(auth()->user()->can('export submissions'))
->color('secondary')
->icon('heroicon-s-arrow-down-tray')
->action(fn () => (new SubmissionsExport)->download('submissions-export-' . date('Y-m-d-i-h-s') . '.xlsx'))
->action(fn () => (new SubmissionsMediaExport)->download('submissions-media-export-' . date('Y-m-d-i-h-s') . '.zip'))
->successNotificationTitle('Exported. Check your Downloads directory.')
->label('Export Submissions'),
Calling either of these ->action() calls works fine independently, but how can I combine them into one?
14 Replies
cheesegrits
cheesegrits9mo ago
I'm not sure that you can. You can only run one action(). But I don't know what you download() function actually does, so I don't know if you could run two of them from a single action. I suspect not. As in, I don't know what would happen if you did ...
->action(function () {
(new SubmissionsExport)->download('submissions-export-' . date('Y-m-d-i-h-s') . '.xlsx'));
(new SubmissionsMediaExport)->download('submissions-media-export-' . date('Y-m-d-i-h-s') . '.zip'));
})
->action(function () {
(new SubmissionsExport)->download('submissions-export-' . date('Y-m-d-i-h-s') . '.xlsx'));
(new SubmissionsMediaExport)->download('submissions-media-export-' . date('Y-m-d-i-h-s') . '.zip'));
})
Dennis Koch
Dennis Koch9mo ago
I don't think Livewire supports multiple file downloads
cheesegrits
cheesegrits9mo ago
Yeah, that was my feeling.
Dennis Koch
Dennis Koch9mo ago
You could maybe built this yourself using browserEvents and some client side JS Can't you even use $livewire->js() now? The file needs a public signed URL then.
DrByte
DrByte9mo ago
Thanks for the responses. The first export is a streamed download using the maatwebsite Laravel-Excel package (via a Symfony\Component\HttpFoundation\BinaryFileResponse) The second export is a streamed download using Spatie Media Library's MediaStream class (via a \Illuminate\Http\Response) Both stream the output to the browser as a download. I don't know where the intersection is between livewire and laravel in this context, to figure out whether it's worth trying to make it happen in one Action/click ... vs just create another button for the 2nd download. Of course, worst-case I can simply use 2 buttons.
DrByte
DrByte9mo ago
Good point. I went digging. The only thing I could find without code-diving yet is this post by RalphJSmit, where he asks about the possibility of testing mulitiple downloads at once ... implying that multiple was a possibility... But that comment wasn't answered. https://github.com/livewire/livewire/discussions/4205
GitHub
Testing file downloads · livewire livewire · Discussion #4205
There's nothing leaping out at me in the testing docs, apologies if I've overlooked something. I've got a component that has : public function exportCsv() { return response()->stream...
cheesegrits
cheesegrits9mo ago
Again, I may be wrong, but I don't think this is possible even in Laravel. The download is a "response", and you can't send multiple responses. Similarly, in Livewire it's a Livewire response to a Livewire method call. And that discussion you linked doesn't seem to be about multiple downloads. The example code given is still only streaming a single downloaded CSV file.
awcodes
awcodes9mo ago
I think the only thing you can do is zip the files then stream the zip back.
DrByte
DrByte9mo ago
Ya, I've mostly conceded that "multiple downloads" isn't an option. Will go with multiple buttons for now. It's not critical enough to spend days figuring out a hack for it 😄 Appreciate all the responses!
cheesegrits
cheesegrits9mo ago
I don't even think there's a hack for it. I'm pretty sure that after calling download() or streamingDownload() (or whatever it is), the session ends and goes back to the browser. I also can't think of any web UI I've ever used that offers me multiple, serial or concurrent downloads. Downloading requires user interaction in the browser.
DrByte
DrByte9mo ago
Right. I wouldn't have even considered it if I hadn't seen it once (somewhere I can't recall now). But, this app doesn't need this "feature" as anything mission-critical. Not even close to "important". In fact, multiple files at once might even scare the people who will actually click that button anyway 🤣
cheesegrits
cheesegrits9mo ago
If it is done anywhere in a UI, it's almost certainly using JS on the client side to initiate. I don't see any way the server side could "push" a second download.
DrByte
DrByte9mo ago
Ya, I suppose JS could receive a list of download endpoints and then open each in another tab with a URL that points to a route that triggers the additional download. Repeating as necessary.
awcodes
awcodes9mo ago
All multiple downloads I’ve seen even with Dropbox. Zip the selections and download them as the zip.