Skip to content

Commit b58de2e

Browse files
authored
Merge pull request #317 from basemate/sf/action-follow-response-issue-288
Implementing `follow_response` for `action` component
2 parents 89e7d75 + ca12ec1 commit b58de2e

File tree

5 files changed

+224
-3
lines changed

5 files changed

+224
-3
lines changed

app/concepts/matestack/ui/core/action/action.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,27 @@ const componentDef = {
2626
if (self.componentConfig["success"] != undefined && self.componentConfig["success"]["emit"] != undefined) {
2727
matestackEventHub.$emit(self.componentConfig["success"]["emit"], response.data);
2828
}
29-
if (self.componentConfig["success"] != undefined && self.componentConfig["success"]["transition"] != undefined && self.$store != undefined) {
29+
if (self.componentConfig["success"] != undefined
30+
&& self.componentConfig["success"]["transition"] != undefined
31+
&& (
32+
self.componentConfig["success"]["transition"]["follow_response"] == undefined
33+
||
34+
self.componentConfig["success"]["transition"]["follow_response"] === false
35+
)
36+
&& self.$store != undefined
37+
) {
3038
let path = self.componentConfig["success"]["transition"]["path"]
3139
self.$store.dispatch('navigateTo', {url: path, backwards: false})
40+
return;
41+
}
42+
if (self.componentConfig["success"] != undefined
43+
&& self.componentConfig["success"]["transition"] != undefined
44+
&& self.componentConfig["success"]["transition"]["follow_response"] === true
45+
&& self.$store != undefined
46+
) {
47+
let path = response.data["transition_to"] || response.request.responseURL;
48+
self.$store.dispatch('navigateTo', {url: path, backwards: false});
49+
return;
3250
}
3351
})
3452
.catch(function(error){

docs/components/action.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,33 @@ success: {
6262
}
6363
```
6464

65+
When the server redirects to a url, for example after creating a new record, the transition needs to be configured to follow this redirect of the server response.
66+
67+
```ruby
68+
success: {
69+
emit: 'my_action_success',
70+
transition: {
71+
follow_response: true
72+
}
73+
}
74+
```
75+
76+
A controller action that would create a record and then respond with the url the page should transition to, could look like this:
77+
78+
```ruby
79+
class TestModelsController < ApplicationController
80+
include Matestack::Ui::Core::ApplicationHelper
81+
82+
def create
83+
@test_model = TestModel.create(test_model_params)
84+
85+
render json: {
86+
transition_to: test_model_path(@test_model)
87+
}, status: :ok
88+
end
89+
end
90+
```
91+
6592
### Failure
6693

6794
As counterpart to the success part of the action component, there is also the possibility to define the failure behavior. This is what gets triggered after the response to our action returns a failure code, usually in the range of `400` or `500` HTTP status codes.

spec/usage/components/action_spec.rb

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,4 +619,174 @@ def response
619619
#
620620
# end
621621

622+
specify "follow_response option makes a transition follow controllers' transition_to" do
623+
624+
class TestModelsController < ExampleController
625+
include Matestack::Ui::Core::ApplicationHelper
626+
627+
def index
628+
responder_for Pages::FollowResponseExampleApp::ExamplePage
629+
end
630+
631+
def create
632+
@test_model = TestModel.create title: params[:title]
633+
render json: {
634+
transition_to: test_model_path(id: @test_model.id)
635+
}, status: :ok
636+
end
637+
638+
def show
639+
@test_model = TestModel.find params[:id]
640+
responder_for Pages::FollowResponseExampleApp::TestModelPage
641+
end
642+
end
643+
644+
Rails.application.routes.append do
645+
resources :test_models
646+
end
647+
Rails.application.reload_routes!
648+
649+
class Apps::FollowResponseExampleApp < Matestack::Ui::App
650+
def response
651+
components {
652+
heading size: 1, text: "My Example App Layout"
653+
main do
654+
page_content
655+
end
656+
}
657+
end
658+
end
659+
660+
module Pages::FollowResponseExampleApp
661+
end
662+
663+
class Pages::FollowResponseExampleApp::ExamplePage < Matestack::Ui::Page
664+
def response
665+
components {
666+
action action_config do
667+
button text: "Click me!"
668+
end
669+
}
670+
end
671+
672+
def action_config
673+
return {
674+
method: :post,
675+
path: :test_models_path,
676+
data: {
677+
title: "A title for my new test object"
678+
},
679+
success: {
680+
transition: {
681+
follow_response: true
682+
}
683+
}
684+
}
685+
end
686+
687+
end
688+
689+
class Pages::FollowResponseExampleApp::TestModelPage < Matestack::Ui::Page
690+
def response
691+
components {
692+
heading text: @test_model.title, size: 1
693+
plain "This page has been loaded via redirect_to and follow_response."
694+
}
695+
end
696+
end
697+
698+
visit "/test_models"
699+
700+
click_button "Click me!"
701+
702+
expect(page).to have_no_text "Click me"
703+
expect(page).to have_text "A title for my new test object"
704+
expect(page).to have_text "This page has been loaded via redirect_to and follow_response."
705+
706+
end
707+
708+
specify "follow_response option makes a transition follow controllers' redirect_to" do
709+
710+
class TestModelsController < ExampleController
711+
include Matestack::Ui::Core::ApplicationHelper
712+
713+
def index
714+
responder_for Pages::FollowResponseExampleApp::ExamplePage
715+
end
716+
717+
def create
718+
@test_model = TestModel.create title: params[:title]
719+
redirect_to test_model_path(id: @test_model.id)
720+
end
721+
722+
def show
723+
@test_model = TestModel.find params[:id]
724+
responder_for Pages::FollowResponseExampleApp::TestModelPage
725+
end
726+
end
727+
728+
Rails.application.routes.append do
729+
resources :test_models
730+
end
731+
Rails.application.reload_routes!
732+
733+
class Apps::FollowResponseExampleApp < Matestack::Ui::App
734+
def response
735+
components {
736+
heading size: 1, text: "My Example App Layout"
737+
main do
738+
page_content
739+
end
740+
}
741+
end
742+
end
743+
744+
module Pages::FollowResponseExampleApp
745+
end
746+
747+
class Pages::FollowResponseExampleApp::ExamplePage < Matestack::Ui::Page
748+
def response
749+
components {
750+
action action_config do
751+
button text: "Click me!"
752+
end
753+
}
754+
end
755+
756+
def action_config
757+
return {
758+
method: :post,
759+
path: :test_models_path,
760+
data: {
761+
title: "A title for my new test object"
762+
},
763+
success: {
764+
transition: {
765+
follow_response: true
766+
}
767+
}
768+
}
769+
end
770+
771+
end
772+
773+
class Pages::FollowResponseExampleApp::TestModelPage < Matestack::Ui::Page
774+
def response
775+
components {
776+
heading text: @test_model.title, size: 1
777+
plain "This page has been loaded via redirect_to and follow_response."
778+
}
779+
end
780+
end
781+
782+
visit "/test_models"
783+
784+
click_button "Click me!"
785+
786+
expect(page).to have_no_text "Click me"
787+
expect(page).to have_text "A title for my new test object"
788+
expect(page).to have_text "This page has been loaded via redirect_to and follow_response."
789+
790+
end
791+
622792
end

vendor/assets/javascripts/matestack-ui-core.js

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/assets/javascripts/matestack-ui-core.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)