Skip to content

Commit 0b79f99

Browse files
committed
finalized action redirect feature
1 parent 87cb091 commit 0b79f99

File tree

10 files changed

+501
-30
lines changed

10 files changed

+501
-30
lines changed

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

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const componentDef = {
2929
if (self.componentConfig["success"] != undefined && self.componentConfig["success"]["emit"] != undefined) {
3030
matestackEventHub.$emit(self.componentConfig["success"]["emit"], response.data);
3131
}
32+
33+
// transition handling
3234
if (self.componentConfig["success"] != undefined
3335
&& self.componentConfig["success"]["transition"] != undefined
3436
&& (
@@ -47,18 +49,83 @@ const componentDef = {
4749
&& self.componentConfig["success"]["transition"]["follow_response"] === true
4850
&& self.$store != undefined
4951
) {
50-
let path = response.data["transition_to"] || response.request.responseURL;
51-
self.$store.dispatch('navigateTo', {url: path, backwards: false});
52+
let path = response.data["transition_to"] || response.request.responseURL
53+
self.$store.dispatch('navigateTo', {url: path, backwards: false})
54+
return;
55+
}
56+
// redirect handling
57+
if (self.componentConfig["success"] != undefined
58+
&& self.componentConfig["success"]["redirect"] != undefined
59+
&& (
60+
self.componentConfig["success"]["redirect"]["follow_response"] == undefined
61+
||
62+
self.componentConfig["success"]["redirect"]["follow_response"] === false
63+
)
64+
&& self.$store != undefined
65+
) {
66+
let path = self.componentConfig["success"]["redirect"]["path"]
67+
window.location.href = path
68+
return;
69+
}
70+
if (self.componentConfig["success"] != undefined
71+
&& self.componentConfig["success"]["redirect"] != undefined
72+
&& self.componentConfig["success"]["redirect"]["follow_response"] === true
73+
&& self.$store != undefined
74+
) {
75+
let path = response.data["redirect_to"] || response.request.responseURL
76+
window.location.href = path
5277
return;
5378
}
5479
})
5580
.catch(function(error){
5681
if (self.componentConfig["failure"] != undefined && self.componentConfig["failure"]["emit"] != undefined) {
5782
matestackEventHub.$emit(self.componentConfig["failure"]["emit"], error.response.data);
5883
}
59-
if (self.componentConfig["failure"] != undefined && self.componentConfig["failure"]["transition"] != undefined && self.$store != undefined) {
84+
// transition handling
85+
if (self.componentConfig["failure"] != undefined
86+
&& self.componentConfig["failure"]["transition"] != undefined
87+
&& (
88+
self.componentConfig["failure"]["transition"]["follow_response"] == undefined
89+
||
90+
self.componentConfig["failure"]["transition"]["follow_response"] === false
91+
)
92+
&& self.$store != undefined
93+
) {
6094
let path = self.componentConfig["failure"]["transition"]["path"]
6195
self.$store.dispatch('navigateTo', {url: path, backwards: false})
96+
return;
97+
}
98+
if (self.componentConfig["failure"] != undefined
99+
&& self.componentConfig["failure"]["transition"] != undefined
100+
&& self.componentConfig["failure"]["transition"]["follow_response"] === true
101+
&& self.$store != undefined
102+
) {
103+
let path = error.response.data["transition_to"] || response.request.responseURL
104+
self.$store.dispatch('navigateTo', {url: path, backwards: false})
105+
return;
106+
}
107+
// redirect handling
108+
if (self.componentConfig["failure"] != undefined
109+
&& self.componentConfig["failure"]["redirect"] != undefined
110+
&& (
111+
self.componentConfig["failure"]["redirect"]["follow_response"] == undefined
112+
||
113+
self.componentConfig["failure"]["redirect"]["follow_response"] === false
114+
)
115+
&& self.$store != undefined
116+
) {
117+
let path = self.componentConfig["failure"]["redirect"]["path"]
118+
window.location.href = path
119+
return;
120+
}
121+
if (self.componentConfig["failure"] != undefined
122+
&& self.componentConfig["failure"]["redirect"] != undefined
123+
&& self.componentConfig["failure"]["redirect"]["follow_response"] === true
124+
&& self.$store != undefined
125+
) {
126+
let path = error.response.data["redirect_to"] || response.request.responseURL
127+
window.location.href = path
128+
return;
62129
}
63130
})
64131
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ def setup
99
unless options[:success][:transition].nil?
1010
@component_config[:success][:transition][:path] = transition_path options[:success]
1111
end
12+
unless options[:success][:redirect].nil?
13+
@component_config[:success][:redirect][:path] = redirect_path options[:success]
14+
end
1215
end
1316
@component_config[:failure] = options[:failure]
1417
unless options[:failure].nil?
1518
unless options[:failure][:transition].nil?
1619
@component_config[:failure][:transition][:path] = transition_path options[:failure]
1720
end
21+
unless options[:failure][:redirect].nil?
22+
@component_config[:failure][:redirect][:path] = redirect_path options[:failure]
23+
end
1824
end
1925
if options[:notify].nil?
2026
@component_config[:notify] = true
@@ -51,5 +57,20 @@ def transition_path callback_options
5157
end
5258
end
5359

60+
def redirect_path callback_options
61+
begin
62+
if callback_options[:redirect][:path].is_a?(Symbol)
63+
return ::Rails.application.routes.url_helpers.send(
64+
callback_options[:redirect][:path],
65+
callback_options[:redirect][:params]
66+
)
67+
else
68+
return callback_options[:redirect][:path]
69+
end
70+
rescue
71+
raise "Redirect path not found"
72+
end
73+
end
74+
5475
end
5576
end

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,6 @@ const componentDef = {
180180
if (self.componentConfig["failure"] != undefined && self.componentConfig["failure"]["emit"] != undefined) {
181181
matestackEventHub.$emit(self.componentConfig["failure"]["emit"], error.response.data);
182182
}
183-
// if (self.componentConfig["failure"] != undefined && self.componentConfig["failure"]["transition"] != undefined && self.$store != undefined) {
184-
// let path = self.componentConfig["failure"]["transition"]["path"]
185-
// self.$store.dispatch('navigateTo', {url: path, backwards: false})
186-
// }
187-
// if (self.componentConfig["failure"] != undefined && self.componentConfig["failure"]["redirect"] != undefined && self.$store != undefined) {
188-
// let path = self.componentConfig["failure"]["redirect"]["path"]
189-
// window.location.href = path
190-
// }
191183

192184
// transition handling
193185
if (self.componentConfig["failure"] != undefined

docs/components/action.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,52 @@ class TestModelsController < ApplicationController
105105
end
106106
```
107107

108+
#### Perform redirect
109+
110+
We can also perform a redirect (full page load) that only gets triggered on success and also accepts further params:
111+
112+
Please be aware, that emiting a event doen't have an effect when performing a redirect instead of a transition, as the whole page (including the surrounding app) gets reloaded!
113+
114+
```ruby
115+
success: {
116+
emit: 'my_action_success', # doesn't have an effect when using redirect
117+
redirect: {
118+
path: :action_test_page2_path,
119+
params: { id: 42 }
120+
}
121+
}
122+
```
123+
124+
When the server redirects to a url, for example after creating a new record, the redirect needs to be configured to follow this redirect of the server response.
125+
126+
```ruby
127+
success: {
128+
emit: 'my_action_success', # doesn't have an effect when using redirect
129+
redirect: {
130+
follow_response: true
131+
}
132+
}
133+
```
134+
135+
A controller action that would create a record and then respond with the url the page should redirect to, could look like this:
136+
137+
```ruby
138+
class TestModelsController < ApplicationController
139+
include Matestack::Ui::Core::ApplicationHelper
140+
141+
def create
142+
@test_model = TestModel.create(test_model_params)
143+
144+
render json: {
145+
redirect_to: test_model_path(@test_model)
146+
}, status: :ok
147+
end
148+
end
149+
```
150+
151+
Same applies for the `failure` configuration.
152+
153+
108154
### Failure
109155

110156
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/dummy/app/controllers/my_app_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def form_action
4747
}, status: :unprocessable_entity
4848
else
4949
broadcast "test_model_created"
50-
render json: @dummy_model, status: :created
50+
render json: { transition_to: my_second_page_path }, status: :created
5151
end
5252
end
5353

spec/dummy/app/matestack/pages/my_app/my_fourth_page.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,16 @@ def my_form_config
4646
method: :post,
4747
path: :form_action_path,
4848
success: {
49-
emit: "form_succeeded"
49+
# emit: "form_succeeded"
50+
transition: {
51+
follow_response: true
52+
}
5053
},
5154
failure: {
52-
emit: "form_has_errors"
55+
emit: "form_has_errors",
56+
transition: {
57+
path: :my_second_page_path
58+
}
5359
}
5460
}
5561
end

spec/spec_helper.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@
4949
config.display_try_failure_messages = true
5050

5151
# run retry only on features
52-
config.around :each, :js do |ex|
53-
ex.run_with_retry retry: 3
54-
end
52+
# config.around :each, :js do |ex|
53+
# ex.run_with_retry retry: 3
54+
# end
5555

5656
# callback to be run between retries
5757
config.retry_callback = proc do |ex|

0 commit comments

Comments
 (0)