Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: allow actions to render turbo streams #2796

Merged
merged 8 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions app/controllers/avo/actions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ def respond

respond_to do |format|
format.turbo_stream do
case @response[:type]
turbo_response = case @response[:type]
when :keep_modal_open
# Only render the flash messages if the action keeps the modal open
render turbo_stream: turbo_stream.flash_alerts
turbo_stream.flash_alerts
when :download
# Trigger download, removes modal and flash the messages
render turbo_stream: [
[
turbo_stream.download(content: Base64.encode64(@response[:path]), filename: @response[:filename]),
turbo_stream.close_action_modal,
turbo_stream.flash_alerts
Expand All @@ -104,25 +104,33 @@ def respond
frame_id = Avo::ACTIONS_TURBO_FRAME_ID
src, _ = @response[:action].link_arguments(resource: @action.resource, **@response[:navigate_to_action_args])

render turbo_stream: turbo_stream.turbo_frame_set_src(frame_id, src)
turbo_stream.turbo_frame_set_src(frame_id, src)
when :redirect
render turbo_stream: turbo_stream.redirect_to(
turbo_stream.redirect_to(
Avo::ExecutionContext.new(target: @response[:path]).handle,
turbo_frame: @response[:redirect_args][:turbo_frame],
**@response[:redirect_args].except(:turbo_frame)
)
when :close_modal
# Close the modal and flash the messages
render turbo_stream: [
[
turbo_stream.close_action_modal,
turbo_stream.flash_alerts
]
else
# Reload the page
back_path = request.referer || params[:referrer].presence || resources_path(resource: @resource)

render turbo_stream: turbo_stream.redirect_to(back_path)
turbo_stream.redirect_to(back_path)
end

responses = if @action.appended_turbo_streams.present?
Array(turbo_response) + Array(instance_exec(&@action.appended_turbo_streams))
else
Array(turbo_response)
end

render turbo_stream: responses
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions lib/avo/base_action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class BaseAction
attr_accessor :user
attr_reader :arguments
attr_reader :icon
attr_reader :appended_turbo_streams

# TODO: find a differnet way to delegate this to the uninitialized Current variable
delegate :context, to: Avo::Current
Expand Down Expand Up @@ -289,6 +290,10 @@ def authorized?
).handle
end

def append_to_response(turbo_stream)
@appended_turbo_streams = turbo_stream
end

private

def add_message(body, type = :info)
Expand Down
5 changes: 4 additions & 1 deletion spec/dummy/app/avo/actions/test/close_modal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ class Avo::Actions::Test::CloseModal < Avo::BaseAction
}

def handle(**args)
TestBuddy.hi "Hello from Avo::Actions::Test::CloseModal handle method"
succeed "Modal closed!!"
close_modal

append_to_response -> {
turbo_stream.set_title("Cool title")
}
Comment on lines +13 to +15
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't we settled on using an array notation?
I mean, why the extra block?

Suggested change
append_to_response -> {
turbo_stream.set_title("Cool title")
}
append_to_response([
turbo_stream.set_title("Cool title")
])

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could do

append_to_response do
  turbo_stream...
end

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forget about it. A block is enough. I hope users don't mistake it for the Execution Context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LEt's also discuss this possibility

    # turbo_stream_response will be executed instead the default `render turbo_stream: responses` from actions controller
    turbo_stream_response -> {
      render turbo_stream: [
        *default_responses, # can include or not the default responses
        turbo_stream.set_title("Cool title"),
        turbo_stream....
      ]
    }

end
end
2 changes: 2 additions & 0 deletions spec/system/avo/actions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@

fill_in "user_first_name", with: "First name should persist after action."

expect(page).to have_title("Create new user — Avocadelicious")

click_on "Actions"
click_on "Close modal"
Expand All @@ -196,6 +197,7 @@
click_on "Run"
expect(page).not_to have_selector(modal)
expect(page).to have_text "Modal closed!!"
expect(page).to have_title("Cool title")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

expect(page).to have_field('user_first_name', with: 'First name should persist after action.')
end
end
Expand Down
Loading