Skip to content

Commit

Permalink
fix: actions download
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul-Bob committed Dec 20, 2023
1 parent feab8e7 commit 97f746a
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 81 deletions.
63 changes: 26 additions & 37 deletions app/controllers/avo/actions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ def handle
(resource_ids.any? ? @resource.find_record(resource_ids, params: params) : [])
)

respond performed_action.response
@response = performed_action.response
respond
end

private
Expand All @@ -55,44 +56,42 @@ def action_class
end
end

def respond(response)
messages = get_messages response
return keep_modal_open(messages) if response[:keep_modal_open]

response[:type] ||= :reload

if response[:type] == :download
return send_data response[:path], filename: response[:filename]
end
def respond
# Flash the messages collected from the action
flash_messages

respond_to do |format|
format.turbo_stream do
# Flash the messages collected from the action
flash_messages messages

if response[:type] == :redirect
render turbo_stream: turbo_stream.redirect_to(
Avo::ExecutionContext.new(target: response[:path]).handle,
nil,
response[:redirect_args][:turbo_frame],
**response[:redirect_args].except(:turbo_frame)
)
else
redirect_back fallback_location: resources_path(resource: @resource)
case @response[:type]
when :keep_modal_open # Only render the flash messages if the action keeps the modal open
render partial: "avo/partials/flash_alerts"
when :download # Check 'app/views/avo/actions/download.turbo_stream.erb' for more information.
render "avo/actions/download"
when :redirect # Turbo redirect to the path
render turbo_stream: turbo_stream.redirect_to(
Avo::ExecutionContext.new(
target: @response[:path]
).handle,
nil,
@response[:redirect_args][:turbo_frame],
**@response[:redirect_args].except(:turbo_frame)
)
else # Reload the page
redirect_back fallback_location: resources_path(resource: @resource)
end
end
end
end

def get_messages(response)
def get_messages
default_message = {
type: :info,
body: I18n.t("avo.action_ran_successfully")
}

return [default_message] if response[:messages].blank?
return [default_message] if @response[:messages].blank?

response[:messages].select do |message|
@response[:messages].select do |message|
# Remove the silent placeholder messages
message[:type] != :silent
end
Expand All @@ -114,22 +113,12 @@ def decrypted_arguments
)
end

def flash_messages(messages)
messages.each do |message|
def flash_messages
get_messages.each do |message|
flash[message[:type]] = message[:body]
end
end

def keep_modal_open(messages)
flash_messages messages

respond_to do |format|
format.turbo_stream do
render partial: "avo/partials/flash_alerts"
end
end
end

def verify_authorization
raise Avo::NotAuthorizedError.new unless @action.authorized?
end
Expand Down
4 changes: 2 additions & 2 deletions app/javascript/js/controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import CodeFieldController from './controllers/fields/code_field_controller'
import CopyToClipboardController from './controllers/copy_to_clipboard_controller'
import DashboardCardController from './controllers/dashboard_card_controller'
import DateFieldController from './controllers/fields/date_field_controller'
import DownloadController from './controllers/download_controller'
import EasyMdeController from './controllers/fields/easy_mde_controller'
import FilterController from './controllers/filter_controller'
import HiddenInputController from './controllers/hidden_input_controller'
Expand All @@ -19,7 +20,6 @@ import ItemSelectorController from './controllers/item_selector_controller'
import KeyValueController from './controllers/fields/key_value_controller'
import LoadingButtonController from './controllers/loading_button_controller'
import MenuController from './controllers/menu_controller'
import ModalController from './controllers/modal_controller'
import MultipleSelectFilterController from './controllers/multiple_select_filter_controller'
import PerPageController from './controllers/per_page_controller'
import PreviewController from './controllers/preview_controller'
Expand All @@ -46,14 +46,14 @@ application.register('attachments', AttachmentsController)
application.register('boolean-filter', BooleanFilterController)
application.register('copy-to-clipboard', CopyToClipboardController)
application.register('dashboard-card', DashboardCardController)
application.register('download', DownloadController)
application.register('filter', FilterController)
application.register('hidden-input', HiddenInputController)
application.register('input-autofocus', InputAutofocusController)
application.register('item-select-all', ItemSelectAllController)
application.register('item-selector', ItemSelectorController)
application.register('loading-button', LoadingButtonController)
application.register('menu', MenuController)
application.register('modal', ModalController)
application.register('multiple-select-filter', MultipleSelectFilterController)
application.register('per-page', PerPageController)
application.register('preview', PreviewController)
Expand Down
11 changes: 11 additions & 0 deletions app/javascript/js/controllers/download_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Controller } from '@hotwired/stimulus'
import { saveAs } from 'file-saver'

export default class extends Controller {
connect() {
saveAs(
new Blob([this.element.dataset.content]),
this.element.dataset.filename,
)
}
}
20 changes: 0 additions & 20 deletions app/javascript/js/controllers/modal_controller.js

This file was deleted.

16 changes: 16 additions & 0 deletions app/views/avo/actions/download.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<%# Append a div that triggers the download_controller.js %>
<%= turbo_stream.append "actions_show" do %>
<%= content_tag :div,
data: {
controller: "download",
content: @response[:path],
filename: @response[:filename],
} do %>
<% end %>s
<% end %>

<%# Remove the actions_show div %>
<%= turbo_stream.remove "actions_show" %>

<%# Trigger the flash alerts %>
<%= render partial: "avo/partials/flash_alerts" %>
2 changes: 1 addition & 1 deletion app/views/avo/actions/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
size: :sm,
data: {
target: :submit_action,
**@action.class.submit_button_data_attributes
action_target: "submit"
} do %>
<%= @action.confirm_button_label %>
<% end %>
Expand Down
29 changes: 10 additions & 19 deletions lib/avo/base_action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class BaseAction
class_attribute :no_confirmation, default: false
class_attribute :standalone, default: false
class_attribute :visible
class_attribute :may_download_file, default: false
class_attribute :may_download_file
class_attribute :turbo
class_attribute :authorize, default: true

Expand All @@ -36,23 +36,10 @@ class << self
delegate :context, to: ::Avo::Current

def form_data_attributes
# We can't respond with a file download from Turbo se we disable it on the form
if may_download_file
{turbo: turbo || false, remote: false}
else
{turbo: turbo, turbo_frame: :_top}.compact
end
end

# We can't respond with a file download from Turbo se we disable close the modal manually after a while (it's a hack, we know)
def submit_button_data_attributes
attributes = { action_target: "submit" }

if may_download_file
attributes[:action] = "click->modal#delayedClose"
end

attributes
{
turbo: turbo,
turbo_frame: :_top
}.compact
end

def to_param
Expand Down Expand Up @@ -99,6 +86,10 @@ def initialize(record: nil, resource: nil, user: nil, view: nil, arguments: {})

@response ||= {}
@response[:messages] = []

if self.may_download_file.present?
puts "[Avo->] WARNING! Since version 3.2.2 'may_download_file' is unecessary and deprecated on actions. Can be safely removed from #{self.class.name}"
end
end

# Blank method
Expand Down Expand Up @@ -193,7 +184,7 @@ def warn(text)
end

def keep_modal_open
response[:keep_modal_open] = true
response[:type] = :keep_modal_open

self
end
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"eslint-config-airbnb": "^19.0.4",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
"file-saver": "^2.0.5",
"flatpickr": "^4.6.13",
"heroicons": "^2.0.18",
"js-cookie": "^3.0.5",
Expand Down
1 change: 0 additions & 1 deletion spec/dummy/app/avo/actions/download_file.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
class Avo::Actions::DownloadFile < Avo::BaseAction
self.name = "Download file"
self.standalone = true
self.may_download_file = true

# TODO: fix fields for actions
def fields
Expand Down
1 change: 0 additions & 1 deletion spec/dummy/app/avo/actions/export_csv.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
class Avo::Actions::ExportCsv < Avo::BaseAction
self.name = "Export csv"
self.no_confirmation = false
self.may_download_file = true

def handle(**args)
records, resource = args.values_at(:records, :resource)
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2636,6 +2636,11 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"

file-saver@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38"
integrity sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==

fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
Expand Down

0 comments on commit 97f746a

Please sign in to comment.