Skip to content

Commit abe5388

Browse files
committed
Merge branch 'add_redirect_to_option_to_forms_and_actions' into develop
2 parents c5d4351 + 200956e commit abe5388

File tree

11 files changed

+966
-55
lines changed

11 files changed

+966
-55
lines changed

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: 87 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -181,29 +181,55 @@ const componentDef = {
181181
if (self.componentConfig["success"] != undefined && self.componentConfig["success"]["emit"] != undefined) {
182182
matestackEventHub.$emit(self.componentConfig["success"]["emit"], response.data);
183183
}
184-
if (
185-
self.componentConfig["success"] != undefined &&
186-
self.componentConfig["success"]["transition"] != undefined &&
187-
(self.componentConfig["success"]["transition"]["follow_response"] == undefined ||
188-
self.componentConfig["success"]["transition"]["follow_response"] === false) &&
189-
self.$store != undefined
184+
// transition handling
185+
if (self.componentConfig["success"] != undefined
186+
&& self.componentConfig["success"]["transition"] != undefined
187+
&& (
188+
self.componentConfig["success"]["transition"]["follow_response"] == undefined
189+
||
190+
self.componentConfig["success"]["transition"]["follow_response"] === false
191+
)
192+
&& self.$store != undefined
190193
) {
191-
let path = self.componentConfig["success"]["transition"]["path"];
192-
self.$store.dispatch("navigateTo", { url: path, backwards: false });
194+
let path = self.componentConfig["success"]["transition"]["path"]
195+
self.$store.dispatch('navigateTo', {url: path, backwards: false})
193196
return;
194197
}
195-
if (
196-
self.componentConfig["success"] != undefined &&
197-
self.componentConfig["success"]["transition"] != undefined &&
198-
self.componentConfig["success"]["transition"]["follow_response"] === true &&
199-
self.$store != undefined
198+
if (self.componentConfig["success"] != undefined
199+
&& self.componentConfig["success"]["transition"] != undefined
200+
&& self.componentConfig["success"]["transition"]["follow_response"] === true
201+
&& self.$store != undefined
200202
) {
201-
let path = response.data["transition_to"] || response.request.responseURL;
202-
self.$store.dispatch("navigateTo", { url: path, backwards: false });
203+
let path = response.data["transition_to"] || response.request.responseURL
204+
self.$store.dispatch('navigateTo', {url: path, backwards: false})
203205
return;
204206
}
205-
if (self.shouldResetFormOnSuccessfulSubmit()) {
206-
console.log("reset")
207+
// redirect handling
208+
if (self.componentConfig["success"] != undefined
209+
&& self.componentConfig["success"]["redirect"] != undefined
210+
&& (
211+
self.componentConfig["success"]["redirect"]["follow_response"] == undefined
212+
||
213+
self.componentConfig["success"]["redirect"]["follow_response"] === false
214+
)
215+
&& self.$store != undefined
216+
) {
217+
let path = self.componentConfig["success"]["redirect"]["path"]
218+
window.location.href = path
219+
return;
220+
}
221+
if (self.componentConfig["success"] != undefined
222+
&& self.componentConfig["success"]["redirect"] != undefined
223+
&& self.componentConfig["success"]["redirect"]["follow_response"] === true
224+
&& self.$store != undefined
225+
) {
226+
let path = response.data["redirect_to"] || response.request.responseURL
227+
window.location.href = path
228+
return;
229+
}
230+
231+
if (self.shouldResetFormOnSuccessfulSubmit())
232+
{
207233
self.setProps(self.data, null);
208234
self.initValues();
209235
}
@@ -216,13 +242,51 @@ const componentDef = {
216242
if (self.componentConfig["failure"] != undefined && self.componentConfig["failure"]["emit"] != undefined) {
217243
matestackEventHub.$emit(self.componentConfig["failure"]["emit"], error.response.data);
218244
}
219-
if (
220-
self.componentConfig["failure"] != undefined &&
221-
self.componentConfig["failure"]["transition"] != undefined &&
222-
self.$store != undefined
245+
// transition handling
246+
if (self.componentConfig["failure"] != undefined
247+
&& self.componentConfig["failure"]["transition"] != undefined
248+
&& (
249+
self.componentConfig["failure"]["transition"]["follow_response"] == undefined
250+
||
251+
self.componentConfig["failure"]["transition"]["follow_response"] === false
252+
)
253+
&& self.$store != undefined
223254
) {
224-
let path = self.componentConfig["failure"]["transition"]["path"];
225-
self.$store.dispatch("navigateTo", { url: path, backwards: false });
255+
let path = self.componentConfig["failure"]["transition"]["path"]
256+
self.$store.dispatch('navigateTo', {url: path, backwards: false})
257+
return;
258+
}
259+
if (self.componentConfig["failure"] != undefined
260+
&& self.componentConfig["failure"]["transition"] != undefined
261+
&& self.componentConfig["failure"]["transition"]["follow_response"] === true
262+
&& self.$store != undefined
263+
) {
264+
let path = error.response.data["transition_to"] || response.request.responseURL
265+
self.$store.dispatch('navigateTo', {url: path, backwards: false})
266+
return;
267+
}
268+
// redirect handling
269+
if (self.componentConfig["failure"] != undefined
270+
&& self.componentConfig["failure"]["redirect"] != undefined
271+
&& (
272+
self.componentConfig["failure"]["redirect"]["follow_response"] == undefined
273+
||
274+
self.componentConfig["failure"]["redirect"]["follow_response"] === false
275+
)
276+
&& self.$store != undefined
277+
) {
278+
let path = self.componentConfig["failure"]["redirect"]["path"]
279+
window.location.href = path
280+
return;
281+
}
282+
if (self.componentConfig["failure"] != undefined
283+
&& self.componentConfig["failure"]["redirect"] != undefined
284+
&& self.componentConfig["failure"]["redirect"]["follow_response"] === true
285+
&& self.$store != undefined
286+
) {
287+
let path = error.response.data["redirect_to"] || response.request.responseURL
288+
window.location.href = path
289+
return;
226290
}
227291
});
228292
},

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@ def setup
1414
unless options[:success][:transition].nil?
1515
@component_config[:success][:transition][:path] = transition_path options[:success]
1616
end
17+
unless options[:success][:redirect].nil?
18+
@component_config[:success][:redirect][:path] = redirect_path options[:success]
19+
end
1720
end
1821
@component_config[:failure] = options[:failure]
1922
unless options[:failure].nil?
2023
unless options[:failure][:transition].nil?
2124
@component_config[:failure][:transition][:path] = transition_path options[:failure]
2225
end
26+
unless options[:failure][:redirect].nil?
27+
@component_config[:failure][:redirect][:path] = redirect_path options[:failure]
28+
end
2329
end
2430
@tag_attributes.merge!({"@submit.prevent": true})
2531
rescue => e
@@ -54,6 +60,21 @@ def transition_path callback_options
5460
end
5561
end
5662

63+
def redirect_path callback_options
64+
begin
65+
if callback_options[:redirect][:path].is_a?(Symbol)
66+
return ::Rails.application.routes.url_helpers.send(
67+
callback_options[:redirect][:path],
68+
callback_options[:redirect][:params]
69+
)
70+
else
71+
return callback_options[:redirect][:path]
72+
end
73+
rescue
74+
raise "Redirect path not found"
75+
end
76+
end
77+
5778
def form_wrapper
5879
case options[:for]
5980
when Symbol

docs/components/action.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ success: {
8282
}
8383
```
8484

85+
#### Perform transition
86+
8587
We can also perform a transition that only gets triggered on success and also accepts further params:
8688

8789
```ruby
@@ -121,6 +123,52 @@ class TestModelsController < ApplicationController
121123
end
122124
```
123125

126+
#### Perform redirect
127+
128+
We can also perform a redirect (full page load) that only gets triggered on success and also accepts further params:
129+
130+
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!
131+
132+
```ruby
133+
success: {
134+
emit: 'my_action_success', # doesn't have an effect when using redirect
135+
redirect: {
136+
path: :action_test_page2_path,
137+
params: { id: 42 }
138+
}
139+
}
140+
```
141+
142+
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.
143+
144+
```ruby
145+
success: {
146+
emit: 'my_action_success', # doesn't have an effect when using redirect
147+
redirect: {
148+
follow_response: true
149+
}
150+
}
151+
```
152+
153+
A controller action that would create a record and then respond with the url the page should redirect to, could look like this:
154+
155+
```ruby
156+
class TestModelsController < ApplicationController
157+
include Matestack::Ui::Core::ApplicationHelper
158+
159+
def create
160+
@test_model = TestModel.create(test_model_params)
161+
162+
render json: {
163+
redirect_to: test_model_path(@test_model)
164+
}, status: :ok
165+
end
166+
end
167+
```
168+
169+
Same applies for the `failure` configuration.
170+
171+
124172
### Failure
125173

126174
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.

docs/components/form.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,53 @@ class TestModelsController < ApplicationController
185185
end
186186
```
187187

188+
Same applies for the `failure` configuration.
189+
190+
#### Perform redirect
191+
192+
We can also perform a redirect (full page load) that only gets triggered on success and also accepts further params:
193+
194+
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!
195+
196+
```ruby
197+
success: {
198+
emit: 'my_action_success', # doesn't have an effect when using redirect
199+
redirect: {
200+
path: :action_test_page2_path,
201+
params: { id: 42 }
202+
}
203+
}
204+
```
205+
206+
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.
207+
208+
```ruby
209+
success: {
210+
emit: 'my_action_success', # doesn't have an effect when using redirect
211+
redirect: {
212+
follow_response: true
213+
}
214+
}
215+
```
216+
217+
A controller action that would create a record and then respond with the url the page should redirect to, could look like this:
218+
219+
```ruby
220+
class TestModelsController < ApplicationController
221+
include Matestack::Ui::Core::ApplicationHelper
222+
223+
def create
224+
@test_model = TestModel.create(test_model_params)
225+
226+
render json: {
227+
redirect_to: test_model_path(@test_model)
228+
}, status: :ok
229+
end
230+
end
231+
```
232+
233+
Same applies for the `failure` configuration.
234+
188235
#### Reset form
189236

190237
If submitted successfully, the `form` component resets its state by default when using the "post" method. When using the "put" method, the state is not resetted by default. You may control this behavior explictly by using the `reset` option:

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
@@ -45,10 +45,16 @@ def my_form_config
4545
method: :post,
4646
path: :form_action_path,
4747
success: {
48-
emit: "form_succeeded"
48+
# emit: "form_succeeded"
49+
transition: {
50+
follow_response: true
51+
}
4952
},
5053
failure: {
51-
emit: "form_has_errors"
54+
emit: "form_has_errors",
55+
transition: {
56+
path: :my_second_page_path
57+
}
5258
}
5359
}
5460
end

0 commit comments

Comments
 (0)