render_turbo_stream 2.1.2 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +40 -73
- data/app/views/render_turbo_stream_command.html.erb +1 -0
- data/app/views/render_turbo_stream_empty_template.html.erb +0 -0
- data/app/views/{render_turbo_stream.html.erb → render_turbo_stream_request_test.html.erb} +3 -3
- data/lib/render_turbo_stream/channel_libs.rb +94 -0
- data/lib/render_turbo_stream/channel_view_helpers.rb +36 -0
- data/lib/render_turbo_stream/controller_channel_helpers.rb +121 -0
- data/lib/render_turbo_stream/controller_helpers.rb +241 -0
- data/lib/render_turbo_stream/test/request/channel_helpers.rb +55 -0
- data/lib/render_turbo_stream/test/request/helpers.rb +78 -0
- data/lib/render_turbo_stream/test/request/libs.rb +156 -0
- data/lib/render_turbo_stream/version.rb +1 -1
- data/lib/render_turbo_stream.rb +7 -327
- metadata +14 -12
- data/app/models/render_turbo_stream/cable_stream.rb +0 -4
- data/db/migrate/20230428115511_cable_streams.rb +0 -4
- data/db/migrate/20230428115724_create_render_turbo_stream_cable_streams.rb +0 -11
- data/lib/render_turbo_stream/test/request_helpers.rb +0 -100
- data/lib/render_turbo_stream/test/rspec_request_helpers.rb +0 -34
- data/lib/render_turbo_stream/turbo_cable_helpers.rb +0 -75
- data/lib/render_turbo_stream/turbo_cable_view_helpers.rb +0 -36
data/lib/render_turbo_stream.rb
CHANGED
@@ -1,335 +1,15 @@
|
|
1
1
|
require "render_turbo_stream/version"
|
2
2
|
require "render_turbo_stream/railtie"
|
3
3
|
require 'render_turbo_stream/engine'
|
4
|
-
require 'render_turbo_stream/test/request_helpers'
|
5
|
-
require 'render_turbo_stream/test/rspec_request_helpers'
|
6
|
-
require 'render_turbo_stream/turbo_cable_helpers'
|
7
|
-
require 'render_turbo_stream/turbo_cable_view_helpers'
|
8
4
|
|
9
|
-
|
5
|
+
require 'render_turbo_stream/test/request/channel_helpers'
|
6
|
+
require 'render_turbo_stream/test/request/helpers'
|
7
|
+
require 'render_turbo_stream/test/request/libs'
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
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
|
14
|
-
turbo_redirect_on_success_to: nil, # does a full page redirect (break out of all frames by turbo_power redirect)
|
15
|
-
object: nil, # object used in save_action, example: @customer
|
16
|
-
id: nil, # if nil: no partial is rendered
|
17
|
-
partial: nil, # example: 'customers/form' default: "#{controller_path}/#{id}"
|
18
|
-
action: 'replace', # options: append, prepend
|
19
|
-
flash_action: action_name, # options: 'update', 'create', otherwise you have to declare a translation in config/locales like "activerecord.success.#{flash_action}" and "activerecord.errors.#{flash_action}"
|
20
|
-
locals: {}, # locals used by the partial
|
21
|
-
streams_on_success: [
|
22
|
-
{
|
23
|
-
id: nil,
|
24
|
-
partial: 'form',
|
25
|
-
locals: {},
|
26
|
-
action: 'replace'
|
27
|
-
}
|
28
|
-
], # additional partials that should be rendered if save_action succeeded
|
29
|
-
streams_on_error: [
|
30
|
-
{
|
31
|
-
id: nil,
|
32
|
-
partial: 'form',
|
33
|
-
locals: {},
|
34
|
-
action: 'replace'
|
35
|
-
}
|
36
|
-
], # additional partials that should be rendered if save_action failed
|
37
|
-
add_flash_alerts: [], #=> array of strings
|
38
|
-
add_flash_notices: [], #=> array of strings
|
39
|
-
flashes_on_success: [], #=> array of strings
|
40
|
-
flashes_on_error: [] #=> array of strings
|
41
|
-
)
|
9
|
+
require 'render_turbo_stream/controller_helpers'
|
10
|
+
require 'render_turbo_stream/controller_channel_helpers'
|
42
11
|
|
43
|
-
|
44
|
-
object = eval("@#{controller_name.classify.underscore}")
|
45
|
-
end
|
12
|
+
require 'render_turbo_stream/channel_view_helpers'
|
46
13
|
|
47
|
-
|
14
|
+
require 'render_turbo_stream/channel_libs'
|
48
15
|
|
49
|
-
streams = (id ? [id: id, partial: partial, locals: locals, action: action] : [])
|
50
|
-
|
51
|
-
if save_action
|
52
|
-
response.status = 200
|
53
|
-
streams_on_success.each do |s|
|
54
|
-
if s.is_a?(Array)
|
55
|
-
streams.push(s)
|
56
|
-
elsif s.is_a?(Hash) && s[:id].present?
|
57
|
-
streams.push(s)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
else
|
61
|
-
response.status = :unprocessable_entity
|
62
|
-
streams += streams_on_error.select { |s| s[:id].present? }
|
63
|
-
end
|
64
|
-
|
65
|
-
#== FLASHES
|
66
|
-
|
67
|
-
model_name = object.model_name.human
|
68
|
-
if save_action
|
69
|
-
flash_notices = if flashes_on_success.present?
|
70
|
-
flashes_on_success
|
71
|
-
elsif flash_action.to_s == 'create'
|
72
|
-
str = I18n.t(
|
73
|
-
'activerecord.success.successfully_created',
|
74
|
-
default: '%<model_name>s successfully created'
|
75
|
-
)
|
76
|
-
[format(str, model_name: model_name)]
|
77
|
-
elsif flash_action.to_s == 'update'
|
78
|
-
str = I18n.t(
|
79
|
-
'activerecord.success.successfully_updated',
|
80
|
-
default: '%<model_name>s successfully updated'
|
81
|
-
)
|
82
|
-
[format(str, model_name: model_name)]
|
83
|
-
else
|
84
|
-
str = I18n.t(
|
85
|
-
"activerecord.success.#{flash_action}",
|
86
|
-
default: '%<model_name>s successfully updated'
|
87
|
-
)
|
88
|
-
[format(str, model_name: model_name)]
|
89
|
-
end
|
90
|
-
flash_alerts = []
|
91
|
-
else
|
92
|
-
flash_alerts = if flashes_on_error.present?
|
93
|
-
flashes_on_error
|
94
|
-
elsif flash_action.to_s == 'create'
|
95
|
-
str = I18n.t(
|
96
|
-
'activerecord.errors.messages.could_not_create',
|
97
|
-
default: '%<model_name>s could not be created'
|
98
|
-
)
|
99
|
-
[format(str, model_name: model_name)]
|
100
|
-
elsif flash_action.to_s == 'update'
|
101
|
-
str = I18n.t(
|
102
|
-
'activerecord.errors.messages.could_not_update',
|
103
|
-
default: '%<model_name>s could not be updated'
|
104
|
-
)
|
105
|
-
[format(str, model_name: model_name)]
|
106
|
-
else
|
107
|
-
str = I18n.t(
|
108
|
-
"activerecord.errors.messages.#{flash_action}",
|
109
|
-
default: '%<model_name>s could not be updated'
|
110
|
-
)
|
111
|
-
[format(str, model_name: model_name)]
|
112
|
-
end
|
113
|
-
flash_notices = []
|
114
|
-
end
|
115
|
-
|
116
|
-
flash_notices += add_flash_notices.to_a
|
117
|
-
flash_alerts += add_flash_alerts.to_a
|
118
|
-
_flash_id = Rails.configuration.x.render_turbo_stream.flash_id
|
119
|
-
flash_id = (_flash_id ? _flash_id : "ERROR, MISSING CONFIG => config.x.render_turbo_stream.flash_id")
|
120
|
-
flash_partial = Rails.configuration.x.render_turbo_stream.flash_partial
|
121
|
-
flash_action = Rails.configuration.x.render_turbo_stream.flash_action
|
122
|
-
flash_notices.each do |notice|
|
123
|
-
next unless notice.present?
|
124
|
-
# inside the flash partial has to be a loop that handles all theese flashes
|
125
|
-
flash_stream = {
|
126
|
-
id: flash_id,
|
127
|
-
partial: flash_partial,
|
128
|
-
action: flash_action,
|
129
|
-
locals: { success: true, message: notice }
|
130
|
-
}
|
131
|
-
streams.push(flash_stream)
|
132
|
-
end
|
133
|
-
flash_alerts.each do |alert|
|
134
|
-
next unless alert.present?
|
135
|
-
# inside the flash partial has to be a loop that handles all theese flashes
|
136
|
-
flash_stream = {
|
137
|
-
id: flash_id,
|
138
|
-
partial: flash_partial,
|
139
|
-
action: flash_action,
|
140
|
-
locals: { success: false, message: alert }
|
141
|
-
}
|
142
|
-
streams.push(flash_stream)
|
143
|
-
end
|
144
|
-
|
145
|
-
#== render
|
146
|
-
|
147
|
-
if save_action && turbo_redirect_on_success_to.present?
|
148
|
-
response.status = 302
|
149
|
-
flash[:alert] = flash_alerts
|
150
|
-
flash[:notice] = flash_notices
|
151
|
-
Rails.logger.debug(" • Set flash[:alert] => #{flash_alerts}") if flash_alerts.present?
|
152
|
-
Rails.logger.debug(" • Set flash[:notice] => #{flash_notices}") if flash_notices.present?
|
153
|
-
render_turbo_stream([
|
154
|
-
[
|
155
|
-
:redirect_to,
|
156
|
-
turbo_redirect_on_success_to
|
157
|
-
]
|
158
|
-
])
|
159
|
-
elsif save_action && redirect_on_success_to.present?
|
160
|
-
response.status = 302
|
161
|
-
if Rails.configuration.x.render_turbo_stream.use_cable_for_turbo_stream_save && helpers.user_signed_in?
|
162
|
-
streams.each do |s|
|
163
|
-
next unless s.is_a?(Hash)
|
164
|
-
Rails.logger.debug(" • Send by Cable => «#{s}»")
|
165
|
-
partial_to_me(
|
166
|
-
s[:partial],
|
167
|
-
s[:id],
|
168
|
-
action: flash_action,
|
169
|
-
locals: s[:locals]
|
170
|
-
)
|
171
|
-
end
|
172
|
-
|
173
|
-
else
|
174
|
-
flash[:alert] = flash_alerts
|
175
|
-
flash[:notice] = flash_notices
|
176
|
-
Rails.logger.debug(" • Set flash[:alert] => #{flash_alerts}") if flash_alerts.present?
|
177
|
-
Rails.logger.debug(" • Set flash[:notice] => #{flash_notices}") if flash_notices.present?
|
178
|
-
end
|
179
|
-
redirect_to redirect_on_success_to
|
180
|
-
|
181
|
-
else
|
182
|
-
flash.now[:alert] = flash_alerts
|
183
|
-
flash.now[:notice] = flash_notices
|
184
|
-
render_turbo_stream(streams)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
def render_turbo_stream(array)
|
189
|
-
|
190
|
-
ary = []
|
191
|
-
array.each do |pr|
|
192
|
-
if !pr.present?
|
193
|
-
Rails.logger.warn " WARNING render_turbo_stream: Empty element inside attributes: «#{array}»"
|
194
|
-
elsif pr.is_a?(Hash)
|
195
|
-
props = pr.symbolize_keys
|
196
|
-
raise "missing attribute :id in #{props}" if !props[:id].present?
|
197
|
-
part = (props[:partial].present? ? props[:partial] : props[:id]).gsub('-', '_')
|
198
|
-
partial = (part.to_s.include?('/') ? part : [controller_path, part].join('/'))
|
199
|
-
r = props
|
200
|
-
r[:action] = (props[:action].present? ? props[:action] : :replace)
|
201
|
-
r[:partial] = partial
|
202
|
-
ary.push(r)
|
203
|
-
elsif pr.is_a?(Array)
|
204
|
-
raise "array has to contain at least one element: #{pr}" unless pr.first.present?
|
205
|
-
ary.push(pr)
|
206
|
-
else
|
207
|
-
raise "ERROR render_turbo_stream invalid type: Only hash or array allowed"
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
if request.format.to_sym == :turbo_stream
|
212
|
-
render template: 'render_turbo_stream', locals: { streams: ary }, layout: false, formats: :turbo_stream
|
213
|
-
else
|
214
|
-
Rails.logger.debug(" • Render Turbo Stream RENDERING AS HTML because request.format => #{request.format}")
|
215
|
-
render template: 'render_turbo_stream', locals: { streams: ary }, layout: false, formats: :html
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
def stream_partial(
|
220
|
-
id,
|
221
|
-
partial: nil, #=> default: id
|
222
|
-
action: :replace,
|
223
|
-
locals: {}
|
224
|
-
)
|
225
|
-
render_turbo_stream(
|
226
|
-
[
|
227
|
-
{
|
228
|
-
id: id,
|
229
|
-
partial: partial,
|
230
|
-
action: action,
|
231
|
-
locals: locals
|
232
|
-
}
|
233
|
-
]
|
234
|
-
)
|
235
|
-
end
|
236
|
-
|
237
|
-
class Libs
|
238
|
-
def self.all_responses(response)
|
239
|
-
e = Nokogiri::HTML(response.body).search('#rendered-partials').first
|
240
|
-
res = (e.present? ? JSON.parse(e.inner_html) : [])
|
241
|
-
response.headers.each do |k, v|
|
242
|
-
next unless k.match(/^test-turbo-cable-[\d]+$/)
|
243
|
-
h = JSON.parse(v)
|
244
|
-
res.push(h)
|
245
|
-
end
|
246
|
-
res
|
247
|
-
end
|
248
|
-
|
249
|
-
# if partial is one word, its checked against the last behind the slash, example: 'articles/form' matches 'form'
|
250
|
-
|
251
|
-
def self.select_responses(response, id)
|
252
|
-
all = all_responses(response)
|
253
|
-
|
254
|
-
all.select do |a|
|
255
|
-
if id.present?
|
256
|
-
a['target'] == "##{id}"
|
257
|
-
else
|
258
|
-
false
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
end
|
263
|
-
|
264
|
-
def self.stream_targets(response)
|
265
|
-
responses = all_responses(response)
|
266
|
-
targets = []
|
267
|
-
responses.each do |r|
|
268
|
-
if r['target'].is_a?(Array)
|
269
|
-
r['target'].each do |t|
|
270
|
-
targets.push(t) unless targets.include?(t)
|
271
|
-
end
|
272
|
-
else
|
273
|
-
targets.push(r['target']) unless targets.include?(r['target'])
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
targets
|
278
|
-
end
|
279
|
-
|
280
|
-
def self.stream_target_response_count(response, id, total, &block)
|
281
|
-
responses = select_responses(response, id)
|
282
|
-
|
283
|
-
if total && responses.count != total
|
284
|
-
false
|
285
|
-
elsif block_given?
|
286
|
-
res = responses.select do |r|
|
287
|
-
parsed = Nokogiri::HTML(r['html_response'])
|
288
|
-
r = yield parsed
|
289
|
-
r.present?
|
290
|
-
end.length
|
291
|
-
(res == 0 ? nil : res)
|
292
|
-
else
|
293
|
-
responses.length
|
294
|
-
end
|
295
|
-
|
296
|
-
end
|
297
|
-
|
298
|
-
# on most methods the first attribute is the target.
|
299
|
-
# This method checks for that
|
300
|
-
# it includes the methods from turbo-power
|
301
|
-
# used for test helpers
|
302
|
-
def self.first_arg_is_html_id(method)
|
303
|
-
config = Rails.configuration.x.render_turbo_stream.first_argument_is_html_id
|
304
|
-
default = [
|
305
|
-
:graft,
|
306
|
-
:morph,
|
307
|
-
:inner_html,
|
308
|
-
:insert_adjacent_text,
|
309
|
-
:outer_html,
|
310
|
-
:text_content,
|
311
|
-
:add_css_class,
|
312
|
-
:remove_attribute,
|
313
|
-
:remove_css_class,
|
314
|
-
:set_attribute,
|
315
|
-
:set_dataset_attribute,
|
316
|
-
:set_property,
|
317
|
-
:set_style,
|
318
|
-
:set_styles,
|
319
|
-
:set_value,
|
320
|
-
:dispatch_event,
|
321
|
-
:reset_form,
|
322
|
-
:clear_storage,
|
323
|
-
:scroll_into_view,
|
324
|
-
:set_focus,
|
325
|
-
:turbo_frame_reload,
|
326
|
-
:turbo_frame_set_src,
|
327
|
-
:replace,
|
328
|
-
:append,
|
329
|
-
:prepend
|
330
|
-
]
|
331
|
-
(config.present? ? config : default).map { |m| m.to_sym }.include?(method.to_sym)
|
332
|
-
end
|
333
|
-
|
334
|
-
end
|
335
|
-
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: render_turbo_stream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- christian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -39,18 +39,20 @@ files:
|
|
39
39
|
- Rakefile
|
40
40
|
- app/controllers/render_turbo_stream/application_controller.rb
|
41
41
|
- app/controllers/render_turbo_stream/render_turbo_stream_render_controller.rb
|
42
|
-
- app/models/render_turbo_stream/cable_stream.rb
|
43
|
-
- app/views/render_turbo_stream.html.erb
|
44
42
|
- app/views/render_turbo_stream.turbo_stream.erb
|
45
|
-
-
|
46
|
-
-
|
43
|
+
- app/views/render_turbo_stream_command.html.erb
|
44
|
+
- app/views/render_turbo_stream_empty_template.html.erb
|
45
|
+
- app/views/render_turbo_stream_request_test.html.erb
|
47
46
|
- lib/render_turbo_stream.rb
|
47
|
+
- lib/render_turbo_stream/channel_libs.rb
|
48
|
+
- lib/render_turbo_stream/channel_view_helpers.rb
|
49
|
+
- lib/render_turbo_stream/controller_channel_helpers.rb
|
50
|
+
- lib/render_turbo_stream/controller_helpers.rb
|
48
51
|
- lib/render_turbo_stream/engine.rb
|
49
52
|
- lib/render_turbo_stream/railtie.rb
|
50
|
-
- lib/render_turbo_stream/test/
|
51
|
-
- lib/render_turbo_stream/test/
|
52
|
-
- lib/render_turbo_stream/
|
53
|
-
- lib/render_turbo_stream/turbo_cable_view_helpers.rb
|
53
|
+
- lib/render_turbo_stream/test/request/channel_helpers.rb
|
54
|
+
- lib/render_turbo_stream/test/request/helpers.rb
|
55
|
+
- lib/render_turbo_stream/test/request/libs.rb
|
54
56
|
- lib/render_turbo_stream/version.rb
|
55
57
|
- lib/tasks/render_turbo_stream_tasks.rake
|
56
58
|
homepage: https://gitlab.com/sedl/renderturbostream
|
@@ -78,6 +80,6 @@ requirements: []
|
|
78
80
|
rubygems_version: 3.4.12
|
79
81
|
signing_key:
|
80
82
|
specification_version: 4
|
81
|
-
summary:
|
82
|
-
|
83
|
+
summary: Complete rails-like workflow for turbo streams and channels. With testing
|
84
|
+
strategy.
|
83
85
|
test_files: []
|
@@ -1,11 +0,0 @@
|
|
1
|
-
class CreateRenderTurboStreamCableStreams < ActiveRecord::Migration[7.0]
|
2
|
-
def change
|
3
|
-
create_table :render_turbo_stream_cable_streams do |t|
|
4
|
-
t.string :request_id, limit: 80
|
5
|
-
t.text :locals
|
6
|
-
t.string :action, limit: 80
|
7
|
-
t.string :arguments
|
8
|
-
t.timestamps
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
@@ -1,100 +0,0 @@
|
|
1
|
-
module RenderTurboStream
|
2
|
-
module Test
|
3
|
-
module RequestHelpers
|
4
|
-
|
5
|
-
# log as helper for the developer to see which flash is set and which partials are rendered to wich ids
|
6
|
-
def streams_log
|
7
|
-
RenderTurboStream::Libs.all_responses(response)
|
8
|
-
end
|
9
|
-
|
10
|
-
# Returns the path to which turbo_stream.redirect_to would be applied.
|
11
|
-
def turbo_redirect_to
|
12
|
-
resps = RenderTurboStream::Libs.all_responses(response)
|
13
|
-
url = nil
|
14
|
-
resps.each do |r|
|
15
|
-
if r['type'] == 'command'
|
16
|
-
if r['attributes'].first == 'redirect_to'
|
17
|
-
if url
|
18
|
-
url = 'ERROR: REDIRECT CALLED MORE THAN ONCE'
|
19
|
-
else
|
20
|
-
url = r['attributes'].second
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
url
|
26
|
-
end
|
27
|
-
|
28
|
-
def stream_target_response_count(id, total: 1, &block)
|
29
|
-
RenderTurboStream::Libs.stream_target_response_count(response, id, total, &block)
|
30
|
-
end
|
31
|
-
|
32
|
-
def stream_response(id, css: nil, include_string: nil)
|
33
|
-
c = stream_target_response_count(id, total: 1) do |r|
|
34
|
-
if css && include_string
|
35
|
-
r.css(css).inner_html.include?(include_string)
|
36
|
-
elsif include_string
|
37
|
-
r.inner_html.include?(include_string)
|
38
|
-
elsif css
|
39
|
-
r.css(css)
|
40
|
-
else
|
41
|
-
r.inner_html
|
42
|
-
end
|
43
|
-
end
|
44
|
-
c == 1
|
45
|
-
end
|
46
|
-
|
47
|
-
def stream_targets
|
48
|
-
RenderTurboStream::Libs.stream_targets(response)
|
49
|
-
end
|
50
|
-
|
51
|
-
def stream_targets_count
|
52
|
-
stream_targets.length
|
53
|
-
end
|
54
|
-
|
55
|
-
# Returns false if a given action such as "replace" (for: turbo_stream.replace) is not performed exactly once on a given target id. Otherwise, it returns an array of attributes that were used to call the function.
|
56
|
-
# For stream actions, this only works if the given action has the HTML-ID as its first element.
|
57
|
-
def stream_action_once(action, id)
|
58
|
-
all_responses = RenderTurboStream::Libs.all_responses(response)
|
59
|
-
counts = {}
|
60
|
-
res = nil
|
61
|
-
all_responses.each do |r|
|
62
|
-
|
63
|
-
if r['type'] == 'command'
|
64
|
-
act = r['attributes'].first
|
65
|
-
is_id = RenderTurboStream::Libs.first_arg_is_html_id(act)
|
66
|
-
if action.to_s == act && is_id && r['attributes'].second == id.to_s
|
67
|
-
k = [act, r['attributes'].second].join('-')
|
68
|
-
counts[k] ||= 0
|
69
|
-
counts[k] += 1
|
70
|
-
if counts[k] == 1
|
71
|
-
res = r['attributes']
|
72
|
-
else
|
73
|
-
res = false
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
elsif r['type'] == 'partial'
|
78
|
-
|
79
|
-
act = r['action']
|
80
|
-
is_id = r['target'][0] == '#'
|
81
|
-
_id = r['target'][1..-1]
|
82
|
-
if action.to_s == act && is_id && _id == id.to_s
|
83
|
-
k = [act, _id].join('-')
|
84
|
-
counts[k] ||= 0
|
85
|
-
counts[k] += 1
|
86
|
-
if counts[k] == 1
|
87
|
-
res = [act, id, { locals: r['locals'] }]
|
88
|
-
else
|
89
|
-
res = false
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
end
|
95
|
-
res
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module RenderTurboStream
|
2
|
-
module Test
|
3
|
-
module RspecRequestHelpers
|
4
|
-
|
5
|
-
# expect status 200 and a each one time response to given ids
|
6
|
-
|
7
|
-
def expect_successful_saved(*ids)
|
8
|
-
responses = RenderTurboStream::Libs.all_responses(response)
|
9
|
-
id_counts = {}
|
10
|
-
responses.each do |r|
|
11
|
-
if r['target'].is_a?(Array)
|
12
|
-
r['target'].each do |t|
|
13
|
-
id = (t[0] == '#' ? t[1..-1] : t)
|
14
|
-
id_counts[t.to_s] ||= 0
|
15
|
-
id_counts[t.to_s] += 1
|
16
|
-
end
|
17
|
-
else
|
18
|
-
id = (r['target'][0] == '#' ? r['target'][1..-1] : r['target'])
|
19
|
-
id_counts[id] ||= 0
|
20
|
-
id_counts[id] += 1
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
expect(response.status).to eq(200)
|
25
|
-
expect(id_counts.keys.length).to eq(ids.length)
|
26
|
-
ids.each do |id|
|
27
|
-
expect(id_counts.key?(id)).to be_truthy
|
28
|
-
expect(id_counts[id]).to eq(1)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
module RenderTurboStream
|
2
|
-
module TurboCableHelpers
|
3
|
-
|
4
|
-
def partial_to_all_authenticated_users
|
5
|
-
raise "Function partial_to_all_authenticated_users is not yet implemented"
|
6
|
-
if user_signed_in?
|
7
|
-
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def partial_to_channel(action, channel, partial, id, locals: nil)
|
12
|
-
|
13
|
-
# add headers for test
|
14
|
-
if Rails.env.test?
|
15
|
-
html = RenderTurboStreamRenderController.render(partial: partial, locals: locals)
|
16
|
-
props = {
|
17
|
-
target: "##{id}",
|
18
|
-
action: action,
|
19
|
-
type: 'cable-partial',
|
20
|
-
partial: partial,
|
21
|
-
locals: locals,
|
22
|
-
html_response: html.to_s
|
23
|
-
}
|
24
|
-
h = response.headers.to_h
|
25
|
-
i = 1
|
26
|
-
loop do
|
27
|
-
k = "test-turbo-cable-#{i}"
|
28
|
-
unless h.keys.include?(k)
|
29
|
-
response.headers[k] = props.to_json
|
30
|
-
break
|
31
|
-
end
|
32
|
-
i += 1
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# send
|
37
|
-
|
38
|
-
Turbo::StreamsChannel.send(
|
39
|
-
"broadcast_#{action}_to",
|
40
|
-
channel.to_s,
|
41
|
-
target: id,
|
42
|
-
partial: partial,
|
43
|
-
locals: locals&.symbolize_keys,
|
44
|
-
layout: false
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
def partial_to_all(action, partial, id, locals: nil)
|
49
|
-
partial_to_channel(action, 'all', partial, id, locals: locals)
|
50
|
-
end
|
51
|
-
|
52
|
-
def partial_to_me(partial, id, action: :replace, locals: nil)
|
53
|
-
begin
|
54
|
-
u_id = helpers.current_user&.id
|
55
|
-
a=1
|
56
|
-
unless u_id.present?
|
57
|
-
Rails.logger.debug(' • SKIP RenderTurboStream.partial_to_me because current_user is nil')
|
58
|
-
return
|
59
|
-
end
|
60
|
-
rescue
|
61
|
-
Rails.logger.debug(' • ERROR RenderTurboStream.partial_to_me because current_user is not available')
|
62
|
-
return
|
63
|
-
end
|
64
|
-
|
65
|
-
partial_to_channel(
|
66
|
-
action,
|
67
|
-
"authenticated-user-#{helpers.current_user.id}",
|
68
|
-
partial,
|
69
|
-
id,
|
70
|
-
locals: locals
|
71
|
-
)
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module RenderTurboStream
|
2
|
-
module TurboCableViewHelpers
|
3
|
-
|
4
|
-
def cable_from_me
|
5
|
-
if current_user
|
6
|
-
turbo_stream_from "authenticated-user-#{current_user.id}"
|
7
|
-
else
|
8
|
-
Rails.logger.debug(" • SKIP CABLE_FROM_ME because not authenticated")
|
9
|
-
nil
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def cable_from_all_authenticated_users
|
14
|
-
raise "Function cable_from_all_authenticated_users is not yet implemented"
|
15
|
-
if user_signed_in?
|
16
|
-
turbo_stream_from "all-authenticated-users"
|
17
|
-
else
|
18
|
-
Rails.logger.debug(" • SKIP CABLE_FROM_ALL_AUTHENTICATED_USERS because not authenticated")
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def cable_from_all
|
24
|
-
turbo_stream_from "all"
|
25
|
-
end
|
26
|
-
|
27
|
-
def local_model(object)
|
28
|
-
if (object.is_a?(String) && object[0..5] == 'gid://') || object.is_a?(GlobalID)
|
29
|
-
GlobalID::Locator.locate(object)
|
30
|
-
else
|
31
|
-
object
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|