render_turbo_stream 3.0.5 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +36 -92
- data/app/views/layouts/_add_turbo_frame_tag.html.erb +6 -0
- data/app/views/render_turbo_stream.turbo_stream.erb +13 -4
- data/app/views/render_turbo_stream_request_test.html.erb +13 -5
- data/lib/render_turbo_stream/channel_libs.rb +58 -14
- data/lib/render_turbo_stream/channel_view_helpers.rb +8 -0
- data/lib/render_turbo_stream/check_template.rb +122 -0
- data/lib/render_turbo_stream/controller_channel_helpers.rb +102 -10
- data/lib/render_turbo_stream/controller_helpers.rb +79 -153
- data/lib/render_turbo_stream/controller_libs.rb +162 -0
- data/lib/render_turbo_stream/libs.rb +35 -0
- data/lib/render_turbo_stream/test/request/channel_helpers.rb +50 -10
- data/lib/render_turbo_stream/test/request/helpers.rb +22 -10
- data/lib/render_turbo_stream/test/request/libs.rb +97 -42
- data/lib/render_turbo_stream/version.rb +1 -1
- data/lib/render_turbo_stream.rb +3 -0
- metadata +13 -9
@@ -2,6 +2,7 @@ module RenderTurboStream
|
|
2
2
|
module ControllerChannelHelpers
|
3
3
|
|
4
4
|
def render_to_all(target_id, action = :replace, partial: nil, template: nil, locals: nil)
|
5
|
+
evaluate_instance_variables
|
5
6
|
render_to_channel(
|
6
7
|
'all',
|
7
8
|
target_id,
|
@@ -26,7 +27,7 @@ module RenderTurboStream
|
|
26
27
|
|
27
28
|
render_to_channel(
|
28
29
|
"authenticated-user-#{helpers.current_user.id}",
|
29
|
-
target_id,
|
30
|
+
RenderTurboStream::Libs.target_id_to_target(target_id),
|
30
31
|
action,
|
31
32
|
partial: partial,
|
32
33
|
locals: locals
|
@@ -47,23 +48,25 @@ module RenderTurboStream
|
|
47
48
|
|
48
49
|
render_to_channel(
|
49
50
|
"authenticated-group-#{group}",
|
50
|
-
target_id,
|
51
|
+
RenderTurboStream::Libs.target_id_to_target(target_id),
|
51
52
|
action,
|
52
53
|
partial: partial,
|
53
54
|
locals: locals
|
54
55
|
)
|
55
56
|
end
|
56
57
|
|
57
|
-
def render_to_channel(channel, target_id, action, partial: nil, template: nil, locals: nil)
|
58
|
+
def render_to_channel(channel, target_id, action, partial: nil, template: nil, locals: nil, instance_variables: true)
|
59
|
+
|
60
|
+
raise 'Arguments partial and template cannot both be specified' if partial && template
|
58
61
|
|
59
62
|
disable_default = false
|
60
|
-
if partial
|
61
|
-
|
62
|
-
elsif template.present?
|
63
|
-
|
63
|
+
if partial.present?
|
64
|
+
_partial = RenderTurboStream::Libs.partial_path(nil, target_id, controller_path, partial)
|
65
|
+
elsif template.present?
|
66
|
+
_template = RenderTurboStream::Libs.partial_path(nil, target_id, controller_path, template)
|
64
67
|
disable_default = true
|
65
68
|
else
|
66
|
-
|
69
|
+
_template = [controller_path, action_name].join('/')
|
67
70
|
disable_default = true
|
68
71
|
end
|
69
72
|
|
@@ -73,7 +76,17 @@ module RenderTurboStream
|
|
73
76
|
@render_cable_template_was_called = true
|
74
77
|
end
|
75
78
|
|
76
|
-
|
79
|
+
evaluate_instance_variables
|
80
|
+
|
81
|
+
libs = RenderTurboStream::ChannelLibs.new(response)
|
82
|
+
libs.render_to_channel(
|
83
|
+
channel,
|
84
|
+
RenderTurboStream::Libs.target_id_to_target(target_id),
|
85
|
+
action,
|
86
|
+
self,
|
87
|
+
template: _template,
|
88
|
+
partial: _partial, locals: locals
|
89
|
+
)
|
77
90
|
|
78
91
|
end
|
79
92
|
|
@@ -114,7 +127,86 @@ module RenderTurboStream
|
|
114
127
|
end
|
115
128
|
|
116
129
|
def action_to_channel(channel, command, arguments)
|
117
|
-
RenderTurboStream::ChannelLibs.
|
130
|
+
libs = RenderTurboStream::ChannelLibs.new(response)
|
131
|
+
libs.action_to_channel(channel, command, arguments)
|
132
|
+
end
|
133
|
+
|
134
|
+
def turbo_channel_save(
|
135
|
+
save_action,
|
136
|
+
object: nil, # object used in save_action, example: @customer
|
137
|
+
|
138
|
+
if_success_redirect_to: nil, # does a regular redirect. Works if you are inside a turbo_frame and just want to redirect inside that frame BUT CANNOT STREAM OTHERS ACTIONS ON THE SAME RESPONSE https://github.com/rails/rails/issues/48056
|
139
|
+
|
140
|
+
if_success: nil, # hash for a partial to render or array with actions (as array) or hashes for partials within
|
141
|
+
if_error: nil, # additional partials that should be rendered if save_action failed
|
142
|
+
add: [], # additional streams
|
143
|
+
|
144
|
+
if_success_notices: nil, # array of strings, override default generated flash generation in the case of success
|
145
|
+
if_error_alerts: nil,
|
146
|
+
add_notices: nil, # array of strings
|
147
|
+
add_alerts: nil,
|
148
|
+
|
149
|
+
flash_controller_action_name: action_name, # options: 'update', 'create', otherwise you have to declare a translation in config/locales like "activerecord.success.#{flash_controller_action_name}" and "activerecord.errors.#{flash_controller_action_name}"
|
150
|
+
instance_variables: true # options: if false, nothing happens, if true: Instance variables that matching to controller name like @article or @articles are set to locals. By Array you can add more, example: [:my_var]
|
151
|
+
)
|
152
|
+
|
153
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
154
|
+
# LOGIC
|
155
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
156
|
+
|
157
|
+
unless object
|
158
|
+
object = eval("@#{controller_name.classify.underscore}")
|
159
|
+
end
|
160
|
+
|
161
|
+
libs = RenderTurboStream::ControllerLibs.new(save_action)
|
162
|
+
model_name = object.model_name.human
|
163
|
+
|
164
|
+
turbo_actions = libs.generate_flash(
|
165
|
+
model_name,
|
166
|
+
flash_controller_action_name,
|
167
|
+
if_success_notices,
|
168
|
+
if_error_alerts,
|
169
|
+
add_notices,
|
170
|
+
add_alerts,
|
171
|
+
)[:turbo_actions]
|
172
|
+
|
173
|
+
turbo_actions += libs.additional_actions(
|
174
|
+
if_success,
|
175
|
+
if_error,
|
176
|
+
add
|
177
|
+
)
|
178
|
+
|
179
|
+
if libs.action_errors(turbo_actions).present?
|
180
|
+
raise libs.action_errors(turbo_actions).join(', ')
|
181
|
+
end
|
182
|
+
|
183
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
184
|
+
#== RENDER TO CHANNEL
|
185
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
186
|
+
|
187
|
+
libs = RenderTurboStream::ChannelLibs.new(response)
|
188
|
+
if (helpers.current_user.id rescue false)
|
189
|
+
libs.send_actions_to_channel(
|
190
|
+
"authenticated-user-#{helpers.current_user.id}",
|
191
|
+
turbo_actions,
|
192
|
+
instance_variables: instance_variables
|
193
|
+
)
|
194
|
+
end
|
195
|
+
|
196
|
+
if save_action && if_success_redirect_to.present?
|
197
|
+
response.status = 302
|
198
|
+
redirect_to if_success_redirect_to
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
@render_turbo_stream_evaluate_instance_variables = nil
|
204
|
+
|
205
|
+
def evaluate_instance_variables
|
206
|
+
@render_turbo_stream_evaluate_instance_variables ||= (
|
207
|
+
{ var_test: 'alpha' }
|
208
|
+
)
|
209
|
+
|
118
210
|
end
|
119
211
|
|
120
212
|
end
|
@@ -2,187 +2,118 @@ module RenderTurboStream
|
|
2
2
|
module ControllerHelpers
|
3
3
|
|
4
4
|
# Handles translated flash messages as defined in translations and configs.
|
5
|
-
# If :
|
5
|
+
# If :if_success_redirect_to and channel set up and allow_channel_to_me_for_turbo_stream_save are configured, sends flash message by channel_to_me.
|
6
6
|
# you can add more stream actions to the same response
|
7
7
|
|
8
8
|
def turbo_stream_save(
|
9
9
|
save_action,
|
10
|
-
redirect_on_success_to: nil, # does a regular redirect. Works if you are inside a turbo_frame and just want to redirect inside that frame BUT CANNOT STREAM OTHERS ACTIONS ON THE SAME RESPONSE https://github.com/rails/rails/issues/48056
|
11
|
-
turbo_redirect_on_success_to: nil, # does a full page redirect (break out of all frames by turbo_power redirect)
|
12
10
|
object: nil, # object used in save_action, example: @customer
|
13
|
-
|
14
|
-
|
11
|
+
|
12
|
+
if_success_redirect_to: nil, # does a regular redirect. Works if you are inside a turbo_frame and just want to redirect inside that frame BUT CANNOT STREAM OTHERS ACTIONS ON THE SAME RESPONSE https://github.com/rails/rails/issues/48056
|
13
|
+
if_success_turbo_redirect_to: nil, # does a full page redirect (break out of all frames by turbo_power redirect)
|
14
|
+
|
15
|
+
target_id: nil, # IF NIL: no partial will be rendered AND IF allowed by config: it would send by channel *_to_me and not affect the default response-rendering
|
16
|
+
partial: nil,
|
15
17
|
action: 'replace', # options: append, prepend
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
id: nil,
|
29
|
-
partial: 'form',
|
30
|
-
locals: {},
|
31
|
-
action: 'replace'
|
32
|
-
}
|
33
|
-
], # additional partials that should be rendered if save_action failed
|
34
|
-
add_flash_alerts: [], #=> array of strings
|
35
|
-
add_flash_notices: [], #=> array of strings
|
36
|
-
flashes_on_success: [], #=> array of strings
|
37
|
-
flashes_on_error: [] #=> array of strings
|
18
|
+
locals: {}, # locals used by the target_id
|
19
|
+
|
20
|
+
if_success: nil, # hash for a partial to render or array with actions (as array) or hashes for partials within
|
21
|
+
if_error: nil, # additional partials that should be rendered if save_action failed
|
22
|
+
add: [], # additional streams
|
23
|
+
|
24
|
+
if_success_notices: nil, # array of strings, override default generated flash generation in the case of success
|
25
|
+
if_error_alerts: nil,
|
26
|
+
add_notices: nil, # array of strings
|
27
|
+
add_alerts: nil,
|
28
|
+
|
29
|
+
flash_controller_action_name: action_name # options: 'update', 'create', otherwise you have to declare a translation in config/locales like "activerecord.success.#{flash_controller_action_name}" and "activerecord.errors.#{flash_controller_action_name}"
|
38
30
|
)
|
39
31
|
|
32
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
33
|
+
# EXCEPTIONS
|
34
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
35
|
+
|
36
|
+
raise 'render_turbo_stream: arguments target_id and if_success_redirect_to cannot be provided both' if target_id && if_success_redirect_to
|
37
|
+
|
38
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
39
|
+
# LOGIC
|
40
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
41
|
+
|
40
42
|
unless object
|
41
43
|
object = eval("@#{controller_name.classify.underscore}")
|
42
44
|
end
|
43
45
|
|
44
|
-
|
46
|
+
libs = RenderTurboStream::ControllerLibs.new(save_action)
|
47
|
+
model_name = object.model_name.human
|
45
48
|
|
46
|
-
streams = (
|
49
|
+
streams = (target_id ? libs.generate_action(controller_path, target_id, action, partial, locals) : [])
|
50
|
+
|
51
|
+
flashes = libs.generate_flash(
|
52
|
+
model_name,
|
53
|
+
flash_controller_action_name,
|
54
|
+
if_success_notices,
|
55
|
+
if_error_alerts,
|
56
|
+
add_notices,
|
57
|
+
add_alerts,
|
58
|
+
)
|
59
|
+
streams += flashes[:turbo_actions]
|
60
|
+
|
61
|
+
streams += libs.additional_actions(
|
62
|
+
if_success,
|
63
|
+
if_error,
|
64
|
+
add
|
65
|
+
)
|
47
66
|
|
48
|
-
if
|
49
|
-
|
50
|
-
streams_on_success.each do |s|
|
51
|
-
if s.is_a?(Array)
|
52
|
-
streams.push(s)
|
53
|
-
elsif s.is_a?(Hash) && s[:id].present?
|
54
|
-
streams.push(s)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
else
|
58
|
-
response.status = :unprocessable_entity
|
59
|
-
streams += streams_on_error.select { |s| s[:id].present? }
|
67
|
+
if libs.action_errors(streams).present?
|
68
|
+
raise libs.action_errors(streams).join(', ')
|
60
69
|
end
|
61
70
|
|
62
|
-
|
63
|
-
|
64
|
-
model_name = object.model_name.human
|
65
|
-
if save_action
|
66
|
-
flash_notices = if flashes_on_success.present?
|
67
|
-
flashes_on_success
|
68
|
-
elsif flash_action.to_s == 'create'
|
69
|
-
str = I18n.t(
|
70
|
-
'activerecord.success.successfully_created',
|
71
|
-
default: '%<model_name>s successfully created'
|
72
|
-
)
|
73
|
-
[format(str, model_name: model_name)]
|
74
|
-
elsif flash_action.to_s == 'update'
|
75
|
-
str = I18n.t(
|
76
|
-
'activerecord.success.successfully_updated',
|
77
|
-
default: '%<model_name>s successfully updated'
|
78
|
-
)
|
79
|
-
[format(str, model_name: model_name)]
|
80
|
-
else
|
81
|
-
str = I18n.t(
|
82
|
-
"activerecord.success.#{flash_action}",
|
83
|
-
default: '%<model_name>s successfully updated'
|
84
|
-
)
|
85
|
-
[format(str, model_name: model_name)]
|
86
|
-
end
|
87
|
-
flash_alerts = []
|
88
|
-
else
|
89
|
-
flash_alerts = if flashes_on_error.present?
|
90
|
-
flashes_on_error
|
91
|
-
elsif flash_action.to_s == 'create'
|
92
|
-
str = I18n.t(
|
93
|
-
'activerecord.errors.messages.could_not_create',
|
94
|
-
default: '%<model_name>s could not be created'
|
95
|
-
)
|
96
|
-
[format(str, model_name: model_name)]
|
97
|
-
elsif flash_action.to_s == 'update'
|
98
|
-
str = I18n.t(
|
99
|
-
'activerecord.errors.messages.could_not_update',
|
100
|
-
default: '%<model_name>s could not be updated'
|
101
|
-
)
|
102
|
-
[format(str, model_name: model_name)]
|
103
|
-
else
|
104
|
-
str = I18n.t(
|
105
|
-
"activerecord.errors.messages.#{flash_action}",
|
106
|
-
default: '%<model_name>s could not be updated'
|
107
|
-
)
|
108
|
-
[format(str, model_name: model_name)]
|
109
|
-
end
|
110
|
-
flash_notices = []
|
71
|
+
unless save_action
|
72
|
+
response.status = 422
|
111
73
|
end
|
112
74
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
flash_id = (_flash_id ? _flash_id : "ERROR, MISSING CONFIG => config.x.render_turbo_stream.flash_id")
|
117
|
-
flash_partial = Rails.configuration.x.render_turbo_stream.flash_partial
|
118
|
-
flash_action = Rails.configuration.x.render_turbo_stream.flash_action
|
119
|
-
flash_notices.each do |notice|
|
120
|
-
next unless notice.present?
|
121
|
-
# inside the flash partial has to be a loop that handles all theese flashes
|
122
|
-
flash_stream = {
|
123
|
-
id: flash_id,
|
124
|
-
partial: flash_partial,
|
125
|
-
action: flash_action,
|
126
|
-
locals: { success: true, message: notice }
|
127
|
-
}
|
128
|
-
streams.push(flash_stream)
|
129
|
-
end
|
130
|
-
flash_alerts.each do |alert|
|
131
|
-
next unless alert.present?
|
132
|
-
# inside the flash partial has to be a loop that handles all theese flashes
|
133
|
-
flash_stream = {
|
134
|
-
id: flash_id,
|
135
|
-
partial: flash_partial,
|
136
|
-
action: flash_action,
|
137
|
-
locals: { success: false, message: alert }
|
138
|
-
}
|
139
|
-
streams.push(flash_stream)
|
140
|
-
end
|
75
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
76
|
+
#== RENDER TO STREAM
|
77
|
+
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
141
78
|
|
142
|
-
|
79
|
+
allow_channel = (Rails.configuration.x.render_turbo_stream.allow_channel_to_me_for_turbo_stream_save rescue false) && (helpers.current_user.id.present? rescue false)
|
143
80
|
|
144
|
-
if save_action &&
|
81
|
+
if save_action && if_success_turbo_redirect_to.present?
|
145
82
|
response.status = 302
|
146
|
-
flash[:alert] =
|
147
|
-
flash[:notice] =
|
148
|
-
Rails.logger.debug(" • Set flash[:alert] => #{
|
149
|
-
Rails.logger.debug(" • Set flash[:notice] => #{
|
83
|
+
flash[:alert] = flashes[:alerts]
|
84
|
+
flash[:notice] = flashes[:notices]
|
85
|
+
Rails.logger.debug(" • Set flash[:alert] => #{flashes[:alerts]}") if flashes[:alerts].present?
|
86
|
+
Rails.logger.debug(" • Set flash[:notice] => #{flashes[:notices]}") if flashes[:notices].present?
|
150
87
|
render_turbo_stream([
|
151
88
|
[
|
152
89
|
:redirect_to,
|
153
|
-
|
90
|
+
if_success_turbo_redirect_to
|
154
91
|
]
|
155
92
|
])
|
156
|
-
elsif save_action &&
|
93
|
+
elsif save_action && if_success_redirect_to.present?
|
157
94
|
response.status = 302
|
158
|
-
if
|
159
|
-
streams.
|
160
|
-
|
161
|
-
|
162
|
-
render_to_me(
|
163
|
-
s[:id],
|
164
|
-
flash_action,
|
165
|
-
partial: s[:partial],
|
166
|
-
locals: s[:locals]
|
167
|
-
)
|
168
|
-
end
|
169
|
-
|
95
|
+
if allow_channel
|
96
|
+
Rails.logger.debug(" • Sent #{streams.length} actions through Turbo::StreamsChannel to enable defined redirection because allowed in configs.")
|
97
|
+
c_libs = RenderTurboStream::ChannelLibs.new(response)
|
98
|
+
c_libs.send_actions_to_channel("authenticated-user-#{helpers.current_user.id}", streams, @render_turbo_stream_evaluate_instance_variables)
|
170
99
|
else
|
171
100
|
flash[:alert] = flash_alerts
|
172
101
|
flash[:notice] = flash_notices
|
173
102
|
Rails.logger.debug(" • Set flash[:alert] => #{flash_alerts}") if flash_alerts.present?
|
174
103
|
Rails.logger.debug(" • Set flash[:notice] => #{flash_notices}") if flash_notices.present?
|
175
104
|
end
|
176
|
-
redirect_to
|
105
|
+
redirect_to if_success_redirect_to
|
106
|
+
|
107
|
+
elsif !target_id.present? && allow_channel
|
108
|
+
Rails.logger.debug(" • Sent #{streams.length} actions through Turbo::StreamsChannel because no target_id defined and allowed in configs.")
|
109
|
+
c_libs = RenderTurboStream::ChannelLibs.new(response)
|
110
|
+
c_libs.send_actions_to_channel("authenticated-user-#{helpers.current_user.id}", streams, @render_turbo_stream_evaluate_instance_variables)
|
177
111
|
|
178
112
|
else
|
179
|
-
flash.now[:alert] = flash_alerts
|
180
|
-
flash.now[:notice] = flash_notices
|
181
113
|
render_turbo_stream(streams)
|
182
114
|
end
|
183
115
|
end
|
184
116
|
|
185
|
-
|
186
117
|
# renders a array of partials to send by turbo-stream and / or actions like turbo_power gem includes, to turbo_stream
|
187
118
|
def render_turbo_stream(array)
|
188
119
|
|
@@ -192,12 +123,12 @@ module RenderTurboStream
|
|
192
123
|
Rails.logger.warn " WARNING render_turbo_stream: Empty element inside attributes: «#{array}»"
|
193
124
|
elsif pr.is_a?(Hash)
|
194
125
|
props = pr.symbolize_keys
|
195
|
-
raise "missing attribute :id in #{props}" if !props[:id].present?
|
196
|
-
part = (props[:partial].present? ? props[:partial] : props[:id]).gsub('-', '_')
|
197
|
-
partial = (part.to_s.include?('/') ? part : [controller_path, part].join('/'))
|
198
126
|
r = props
|
127
|
+
r[:target] = RenderTurboStream::Libs.target_id_to_target(props[:target_id]) if props[:target_id].present?
|
128
|
+
raise "Missing attribute :target in #{props}" if !props[:target].present?
|
129
|
+
r.delete(:target_id)
|
199
130
|
r[:action] = (props[:action].present? ? props[:action] : :replace)
|
200
|
-
r[:partial] = partial
|
131
|
+
r[:partial] = RenderTurboStream::Libs.partial_path(props[:target], props[:target_id], controller_path, props[:partial])
|
201
132
|
r[:type] = 'stream-partial'
|
202
133
|
ary.push(r)
|
203
134
|
elsif pr.is_a?(Array)
|
@@ -219,16 +150,11 @@ module RenderTurboStream
|
|
219
150
|
|
220
151
|
# renders a partial to turbo_stream
|
221
152
|
|
222
|
-
def stream_partial(
|
223
|
-
id,
|
224
|
-
partial: nil, #=> default: id
|
225
|
-
action: :replace,
|
226
|
-
locals: {}
|
227
|
-
)
|
153
|
+
def stream_partial( target_id, partial: nil, action: :replace, locals: {} )
|
228
154
|
render_turbo_stream(
|
229
155
|
[
|
230
156
|
{
|
231
|
-
|
157
|
+
target: RenderTurboStream::Libs.target_id_to_target(target_id),
|
232
158
|
partial: partial,
|
233
159
|
action: action,
|
234
160
|
locals: locals
|
@@ -0,0 +1,162 @@
|
|
1
|
+
module RenderTurboStream
|
2
|
+
class ControllerLibs
|
3
|
+
|
4
|
+
def initialize(save_action)
|
5
|
+
@save_action = save_action
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_flash( model_name, controller_action, if_success_notices, if_error_alerts, add_notices, add_alerts )
|
9
|
+
|
10
|
+
target_id = (Rails.configuration.x.render_turbo_stream.flash_target_id rescue nil)
|
11
|
+
raise "Missing configuration: config.x.render_turbo_stream.flash_target_id" unless target_id
|
12
|
+
partial = Rails.configuration.x.render_turbo_stream.flash_partial
|
13
|
+
raise "Missing configuration: configuration.x.render_turbo_stream.flash_partial" unless partial
|
14
|
+
turbo_action = Rails.configuration.x.render_turbo_stream.flash_turbo_action
|
15
|
+
raise "Missing configuration: configuration.x.render_turbo_stream.flash_turbo_action" unless turbo_action
|
16
|
+
|
17
|
+
|
18
|
+
if @save_action
|
19
|
+
notices = if if_success_notices
|
20
|
+
if_success_notices
|
21
|
+
elsif controller_action.to_sym == :create
|
22
|
+
str = I18n.t(
|
23
|
+
'activerecord.success.successfully_created',
|
24
|
+
default: '%<model_name>s successfully created'
|
25
|
+
)
|
26
|
+
[format(str, model_name: model_name)]
|
27
|
+
elsif controller_action.to_sym == :update
|
28
|
+
str = I18n.t(
|
29
|
+
'activerecord.success.successfully_updated',
|
30
|
+
default: '%<model_name>s successfully updated'
|
31
|
+
)
|
32
|
+
[format(str, model_name: model_name)]
|
33
|
+
else
|
34
|
+
str = I18n.t(
|
35
|
+
"activerecord.success.#{controller_action}",
|
36
|
+
default: '%<model_name>s successfully updated'
|
37
|
+
)
|
38
|
+
[format(str, model_name: model_name)]
|
39
|
+
end
|
40
|
+
alerts = []
|
41
|
+
else
|
42
|
+
alerts = if if_error_alerts
|
43
|
+
if_error_alerts
|
44
|
+
elsif controller_action.to_sym == :create
|
45
|
+
str = I18n.t(
|
46
|
+
'activerecord.errors.messages.could_not_create',
|
47
|
+
default: '%<model_name>s could not be created'
|
48
|
+
)
|
49
|
+
[format(str, model_name: model_name)]
|
50
|
+
elsif controller_action.to_sym == :update
|
51
|
+
str = I18n.t(
|
52
|
+
'activerecord.errors.messages.could_not_update',
|
53
|
+
default: '%<model_name>s could not be updated'
|
54
|
+
)
|
55
|
+
[format(str, model_name: model_name)]
|
56
|
+
else
|
57
|
+
str = I18n.t(
|
58
|
+
"activerecord.errors.messages.#{controller_action}",
|
59
|
+
default: '%<model_name>s could not be updated'
|
60
|
+
)
|
61
|
+
[format(str, model_name: model_name)]
|
62
|
+
end
|
63
|
+
notices = []
|
64
|
+
end
|
65
|
+
|
66
|
+
turbo_actions = []
|
67
|
+
notices += add_notices.to_a
|
68
|
+
alerts += add_alerts.to_a
|
69
|
+
notices.each do |notice|
|
70
|
+
next unless notice.present?
|
71
|
+
flash_stream = {
|
72
|
+
target: RenderTurboStream::Libs.target_id_to_target(target_id),
|
73
|
+
partial: partial,
|
74
|
+
action: turbo_action,
|
75
|
+
locals: { success: true, message: notice }
|
76
|
+
}
|
77
|
+
turbo_actions.push(flash_stream)
|
78
|
+
end
|
79
|
+
alerts.each do |alert|
|
80
|
+
next unless alert.present?
|
81
|
+
flash_stream = {
|
82
|
+
target: RenderTurboStream::Libs.target_id_to_target(target_id),
|
83
|
+
partial: partial,
|
84
|
+
action: turbo_action,
|
85
|
+
locals: { success: false, message: alert }
|
86
|
+
}
|
87
|
+
turbo_actions.push(flash_stream)
|
88
|
+
end
|
89
|
+
{ turbo_actions: turbo_actions, alerts: alerts, notices: notices }
|
90
|
+
end
|
91
|
+
|
92
|
+
def additional_actions( if_success, if_error, add )
|
93
|
+
|
94
|
+
(@save_action ? make_actions(if_success) : make_actions(if_error)) + make_actions(add)
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def generate_action( controller_path, target_id, action, partial, locals )
|
99
|
+
libs = RenderTurboStream::Libs
|
100
|
+
target = libs.target_id_to_target(target_id)
|
101
|
+
_partial = libs.partial_path(nil, target_id, controller_path, partial)
|
102
|
+
[target: target, partial: _partial, locals: locals, action: action]
|
103
|
+
end
|
104
|
+
|
105
|
+
def action_errors(actions)
|
106
|
+
r = []
|
107
|
+
actions.each do |a|
|
108
|
+
if a.is_a?(Hash)
|
109
|
+
unless a[:target].present?
|
110
|
+
r.push("Missing attribute :target for => «#{a}»")
|
111
|
+
end
|
112
|
+
unless a[:partial].present?
|
113
|
+
r.push("Missing attribute :partial for => «#{a}»")
|
114
|
+
end
|
115
|
+
unless a[:action].present?
|
116
|
+
r.push("Missing attribute :action for => «#{a}»")
|
117
|
+
end
|
118
|
+
elsif a.is_a?(Array)
|
119
|
+
unless a.first.is_a?(String) || a.first.is_a?(Symbol)
|
120
|
+
r.push("Assuming a command, but the first attribute must be a string or symbol => «#{a}»")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
r
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
# streamline actions to array
|
130
|
+
# valid inputs for if_success or if_error or add
|
131
|
+
# [:add_css_class, ...]
|
132
|
+
# [[:add_css_class, ..], ..]
|
133
|
+
# {target_id: '..', ..}
|
134
|
+
# [{target_id: '..', ..}, ..]
|
135
|
+
|
136
|
+
def make_actions(actions)
|
137
|
+
res = if actions.present?
|
138
|
+
if actions.is_a?(Hash)
|
139
|
+
[actions]
|
140
|
+
elsif actions.is_a?(Array)
|
141
|
+
if actions.first.is_a?(String) || actions.first.is_a?(Symbol)
|
142
|
+
[actions]
|
143
|
+
else
|
144
|
+
actions
|
145
|
+
end
|
146
|
+
end
|
147
|
+
else
|
148
|
+
[]
|
149
|
+
end
|
150
|
+
res.map do |a|
|
151
|
+
if a.is_a?(Hash) && a.key?(:target_id)
|
152
|
+
a = a.merge(target: "##{a[:target_id]}")
|
153
|
+
a.delete(:target_id)
|
154
|
+
a
|
155
|
+
else
|
156
|
+
a
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RenderTurboStream
|
2
|
+
class Libs
|
3
|
+
|
4
|
+
def self.target_id_to_target(target_id)
|
5
|
+
if target_id.present?
|
6
|
+
"##{target_id}"
|
7
|
+
else
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.target_to_target_id(target)
|
13
|
+
if target.present? && target.to_s[0] == '#'
|
14
|
+
target[1..-1]
|
15
|
+
else
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.partial_path(target, target_id, controller_path, partial)
|
21
|
+
if partial && partial.to_s.include?('/')
|
22
|
+
partial
|
23
|
+
elsif partial.present?
|
24
|
+
[controller_path, partial].join('/')
|
25
|
+
elsif target_id.present?
|
26
|
+
[controller_path, target_id.gsub('-', '_')].join('/')
|
27
|
+
elsif target.present?
|
28
|
+
[controller_path, RenderTurboStream::Libs.target_to_target_id(target).gsub('-', '_')].join('/')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|